X

Recent Posts

ADF

Using the Oracle Public Maven Repository With ADF Applications

Apache Maven lovers, rejoice! Thanks to the Fusion Middleware team, Oracle now has a public repository for you to use! It is located at http://maven.oracle.com. The official Fusion Middleware documentation even contains a section on how to configure your environment to leverage it. While accurate, this documentation is fairly generic. My aim in this post is to explain you how to use the repository with ADF applications. I recorded a video demonstration as well. I started to use Maven with ADF back in 2007, when the first technical previews for 11g were made public. I had used Maven on other Java projects before. I was the architect on a large software development project and wanted my team to implement a workflow build around continuous integration principles. At the time, JDeveloper didn't support Maven. Thus, we had to deploy our own internal repository. I wrote a tool to scan the JDeveloper extensions, extract the various JAR files and import them in the repository. Nowadays, this process is automated; you simply have to use the Maven Synchronization Plug-in. JDeveloper is not only compatible with Maven, but it actually ships with it. This started with Maven 3.0.4 back in version 12.1.2. JDeveloper 12.1.3 brought small but significant improvements to Maven support, and updated the Maven version to 3.0.5. I strongly recommend you to use the Maven release that ships with JDeveloper, as the various Oracle plugins involved may not have been tested with later releases. You will be on your own if you do otherwise. Let's now see in detail how to setup your environment in order to compile and deploy ADF applications with Maven from the command line. Step 1: Register  The repository may be public, but you need to register in order to access it. This is to ensure you have accepted the licence agreement for the artifacts it contains. You can register here:  https://www.oracle.com/webapps/maven/register/license.html. Every time you will access the repository, you will need to provide your OTN user name and password.  Step 2: Create environment variables and alter the path.  The Maven distribution bundled with JDeveloper is located in the following directory.  JDEV_HOME/oracle_common/modules/org.apache.maven_<version> You have to create two environment variables: M2_HOME, which must point to the directory above, and M2, which must be set to %M2_HOME%\bin on Windows or $M2_HOME/bin on Linux and OS X. You must add the M2 variable to the PATH as well. In addition, ensure JAVA_HOME exists and points to a valid Java install. Once you are done, you may test your setup by executing the maven -version command on the command line. Below is the output I get on a Windows 8.1 machine.  Microsoft Windows [Version 6.3.9600](c) 2013 Microsoft Corporation. All rights reserved.C:\Users\Frédéric>mvn -versionApache Maven 3.0.5 (r01de14724cdef164cd33c7c8c2fe155faf9602da; 2013-02-19 08:51:28-0500)Maven home: C:\Oracle\jdev1213\oracle_common\modules\org.apache.maven_3.0.5Java version: 1.7.0_60, vendor: Oracle CorporationJava home: c:\Java64\jdk1.7.0_60\jreDefault locale: en_CA, platform encoding: Cp1252OS name: "windows 8.1", version: "6.3", arch: "amd64", family: "windows"C:\Users\Frédéric> Step 3: Define the repository  You must provide Maven the information it needs in order to connect the repository. This can be achieved by adding a repository definition either to your POM or to Maven's settings.xml file. Personally, I prefer to go the settings.xml route since such information will likely be shared among several applications. Typically, setting.xml is found in the user's home directory under the .m2 subdirectory.  On my Windows machine, the full path is c:\users\Frédéric\.m2. The equivalent path would be /Users/Frédéric/.m2 under OS X. You can learn more about this file on the official Maven website.  To ensure that the repository definitions contained in settings.xml will be available at runtime, they should reside in a profile marked as active by default.  <profiles> <profile> <id>Oracle</id> <activation> <activeByDefault>true</activeByDefault> </activation> <repositories> ... </repository> </repositories> <pluginRepositories> ... </pluginRepositories> </profile></profiles> The repository definition  must look like this: <repositories> <repository> <id>maven.oracle.com</id> <releases> <enabled>true</enabled> <updatePolicy>never</updatePolicy> </releases> <snapshots> <enabled>false</enabled> <updatePolicy>never</updatePolicy> </snapshots> <url>https://maven.oracle.com</url> <layout>default</layout> </repository></repositories><pluginRepositories> <pluginRepository> <id>maven.oracle.com</id> <releases> <enabled>true</enabled> </releases> <snapshots> <enabled>false</enabled> </snapshots> <url>https://maven.oracle.com</url> <layout>default</layout> </pluginRepository></pluginRepositories> Only releases are enabled, since Oracle will not deploy snapshots to the repository. In addition, I set the update policy to never since Oracle will not provide patches or other updates. New artifacts will be published for future releases of ADF, but you will have to explicitly reference the new version numbers in your POMs to pick them up. We did this for stability reasons. The repository is defined twice; once as an artifact repository and once as a plugin repository. The latter is needed since the ojmake and ojdeploy plugins are needed in order to build ADF applications. Moreover, the WebLogic plugin might be required for runtime deployment. This distinction between artifact and plugin repositories has been introduced in Maven 3. Step 4: Update Wagon-http  Wagon-http is a component used by Maven to access remote repositories. The Oracle public Maven repository is protected by the same single sign-on (SSO) solution that other Oracle web sites use. Unfortunately, older versions of wagon-http are not compatible with such enterprise-grade infrastructures. However, it is possible to override the version that is bundled with Maven. To use the Oracle repository, you will need wagon-http 2.8. Simply download the required JAR file from the following location:  http://central.maven.org/maven2/org/apache/maven/wagon/wagon-http/2.8/wagon-http-2.8-shaded.jar You will then need to copy the file to the M2_HOME\lib\ext directory.  Please note that wagon-http 2.8 is included in Maven 3.2.5 and higher. Thus, this step will likely become unnecessary in the future, since new releases of JDeveloper will probably provide an even more recent build of Maven.   Step 5:  Define the server While is is possible to define repositories in the POM, certain settings must absolutely be defined in the settings.xml file. Here is how the server definition look like. <server> <id>maven.oracle.com</id> <username>blueberry.coder@oracle.com</username> <password>{HsygnP77JNIHdWNRgDiuknhzqnt0NFtIpTlQ4jlwOGk=}</password> <configuration><basicAuthScope> <host>ANY</host> <port>ANY</port> <realm>OAM 11g</realm></basicAuthScope><httpConfiguration> <all><params> <property><name>http.protocol.allow-circular-redirects</name><value>%b,true</value> </property></params> </all></httpConfiguration> </configuration></server>  In theory, you could write your password in clear text and things would work. However, Oracle strongly recommends that you encrypt the password using the tools provided by Maven. Step 6: Encrypt your password  There are two tasks to perform in order to complete this step. First, you must generate and store a master password. This password is used to encrypt other passwords and should not be the same used by your Oracle account. To generate it, open a command prompt and execute the following command: mvn --encrypt-master-password <password> This will give you back a string such as {RpmTqVoMD0kHBbAIe2Jq1vdcM8HuPb/uvdnO+R4c67g=}.You should then create a file called settings-security.xml in the same folder as the settings.xml file used by Maven. The contents of this file should look like this: <settingsSecurity> <master>{RpmTqVoMD0kHBbAIe2Jq1vdcM8HuPb/uvdnO+R4c67g=}</master></settingsSecurity>  Once you are done with the master password, you can encrypt the actual password for your account using the command below. mvn --encrypt-password <password>  Simply paste the string returned in the server definition that you created in step 5. Step 7: Add the WebLogic plugin to your POM  If you want to deploy your ADF application to WebLogic through Maven, you will need to reference the appropriate plugin in its top-level POM.  <plugin> <artifactId>weblogic-maven-plugin</artifactId> <groupId>com.oracle.weblogic</groupId> <version>12.1.3-0-0</version> <configuration/> <executions> <execution> <id>wls-deploy</id> <phase>pre-integration-test</phase> <goals> <goal>deploy</goal> </goals> <configuration> <remote>false</remote> <adminurl>t3://127.0.0.1:7777</adminurl> <user>weblogic</user> <password>welcome1</password> <source>${basedir}/deploy/FullMavenTest_Project1_FullMavenTest.ear</source> <targets>DefaultServer</targets> <verbose>true</verbose> <name>${project.build.finalName}</name> </configuration> </execution> </executions></plugin> In this example, the WLS administrative password has been specified in clear text. The userConfigFile and userKeyFile parameters make it possible to encrypt the password, however. In addition, the source parameter must point to the EAR produced by the build process. The name for that EAR is managed through JDeveloper settings, and not through the POM. Moreover, please note that the value for the targets parameter should be set to DefaultServer if you want to deploy to the JDeveloper integrated WLS instance. The WebLogic plugin requires a specific JAR in the classpath in order to execute. This requirement can be fulfilled by adding this dependency to the POM: <dependency> <groupId>com.oracle.weblogic</groupId> <artifactId>weblogic-classes</artifactId> <version>12.1.3-0-0</version> <scope>system</scope> <systemPath>${oracleHome}/wlserver/server/lib/weblogic-classes.jar</systemPath></dependency> The systemPath parameter must be the absolute path to the weblogic-classes.jar file.  Step 8: Update your JDBC settings In the case you plan to deploy your ADF application to WebLogic using Maven, you need to change a specific JDBC setting using JDeveloper. The reason for this is that, normally, the IDE will regenerate the WLS JDBC descriptors at deployment time. Unfortunately, this results in an error message when deploying without JDeveloper, whether through the command line or the WLS console. The specific error message is: « No credential mapper entry found for password indirection ».  To avoid this, create a JDBC datasource on the WLS server and uncheck the following setting in the Application Properties dialog.  Please note that defining a credential mapping using the WLS console will not work.   If you have deployed the application from JDeveloper before, you will need to delete the generated weblogic-jdbc.xml and remove the reference to it inside the weblogic-application.xml descriptor. You will find both files under the src/META-INF subdirectory of the application workspace. Step 9: Let's do this! You are now ready to compile and deploy your application. You can do so on the command line only for the time being. Moreover, you will need to specify a value for the ORACLE_HOME environment variable, since this is normally something JDeveloper will do for you. Here is an example: mvn pre-integration-test -Denv.ORACLE_HOME=c:\Oracle\jdev1213  Just remember to make sure the JDeveloper integrated WLS instance is running before starting the build process if you want to deploy on it. At this time, it is not possible to index the contents of the Oracle public repository. We will need to update JDeveloper in order to make this possible. 

Apache Maven lovers, rejoice! Thanks to the Fusion Middleware team, Oracle now has a public repository for you to use! It is located at http://maven.oracle.com. The official Fusion Middleware...

ADF

GeneratedPassword: a hidden MAF gem

The transition from ADF Mobile to the Oracle Mobile Application Framework earlier this year brought us many great new features. Some of them were very visible, such as new Data Visualization components or the new Oracle Alta UI skin. Others are more difficult to find. In this post, I want to introduce you to one of the latter, namely the GeneratedPassword class, which is part of the oracle.adfmf.framework.api package. The sole function of GeneratedPassword is to generate and manage random passwords. Each of the passwords is identified by a key, which will be used to retrieve it when needed. The passwords are saved to an encrypted credential store, similar to the one used to store user passwords related to login connections. To create a password, simply pass the desired key to the appropriate method along with a seed which will add entropy to the generation algorithm. Subsequent calls to that method using the same key and seed will result in a different password every time.  At this point, maybe you are asking yourself what those random passwords are good for. Personally, I find them very useful to enhance the protection of encrypted SQLite local databases. In the current version of Oracle MAF, it is necessary to provide a password in order to encrypt or decrypt a database. If you hardcode that password, it will be shared by all deployed instances of your application. If one instance is compromised, then all others will be at risk. Using a random password for that use case is a good mitigation measure, since every instance uses a different encryption key. Compromising multiple instance is thus much more time consuming. 

The transition from ADF Mobile to the Oracle Mobile Application Framework earlier this year brought us many great new features. Some of them were very visible, such as new Data...

MAF

Want to bring your APEX Application to iOS and Android? You should consider the Oracle Mobile Application Framework!

For more than 10 years, PL/SQL developers have used Oracle Application Express (APEX) to deliver high quality applications quickly and efficiently. In the last few releases, the product has gained features that make it a good fit for mobile web applications. It now offers mobile and responsive themes, as well as HTML 5 charts and item types, for example. The upcoming APEX 5 will bring a more modern look and feel, as well as reporting features optimized for mobile. Through third party technologies such as Apache Cordova (formerly PhoneGap), it is even possible to wrap a mobile APEX application and distribute it on the Apple App Store and the Google Play Store. Such applications can even send SMS, access the contact book or take pictures; in other words, they can use the native features of mobile devices.  The main downside of mobile APEX applications is that they cannot be used in offline mode. In other words: those applications are server-based and do not actually run on the phone or tablet. Wrapping the application using Cordova does not change this. No network? No application. Obviously, you could build an entire cross-platform application using Cordova or other comparable toolkits. But this means you will have to work directly with HTML 5, CCS 3 and JavaScript. Those are well-known, flexible and powerful technologies. However, they don't offer the simplicity and productivity you have with APEX. Do not forget that mobile devices are very diverse, especially due to the extreme fragmentation of the Android ecosystem. If you go down the HTML / CSS / JavaScript route, you will have to validate your application in a wide array of scenarios yourself. This is a time-consuming and error-prone process. We at Oracle think there is a better way. Oracle's Mobile Application Framework (MAF) enables you to build on-device iOS and Android applications without extensive HTML, CSS or JavaScript knowledge. This is possible since MAF developers work with components to design the user interface. Those components are rendered in HTML, CSS and JavaScript at runtime and are validated against a comprehensive set of mobile devices and operating systems. In addition, with MAF, you can target the two dominant mobile operating systems from a single Java code base. Moreover, MAF applications can store local data in an encrypted on-device database, and integrate out of the box with Oracle’s identity management solutions. MAF brings mobile developers the same ease of use and productivity that web developers have with APEX .  Applications built with MAF rely on web services to fetch data and initiate transactions. Thus, you can still use PL/SQL and APEX on the server side. It is also possible to integrate remote APEX web pages directly in the frame of a MAF application, thus providing a seamless user experience. Let's now have a look at how this is achieved, before exploring the various ways there are to create web services from PL/SQL logic.  MAF and remote APEX mobile web pages  If you want to leverage your existing APEX Mobile web pages in a MAF application, you have two options:  to integrate a whole application as a remote URL or to use a local HTML 5 page and display select remote pages inside an iFrame. Which option to choose depends on what you are trying to achieve. Remote URLs are very simple to use, but cannot accept dynamic parameters for the time being. They can be featured on the application’s springboard and navigation bar, however. Using an iFrame in a local HTML 5 page is more flexible, since it is possible to add parameters to the remote URL among other things. This approach works well if you need to integrate a few selected remote pages in features otherwise local to the device. Please note it is possible to leverage Oracle Access Manager to achieve single sign-on between the mobile application and the web application in both cases. If you choose to integrate remote APEX pages in your MAF application, you must ensure the APEX application uses a mobile template and design its user interface in a way that will make it usable on the target devices. Furthermore, it is possible to give remote APEX mobile applications access to the MAF APIs. That way, remote pages can access the device's native features, such as the camera or GPS. The process is currently a bit cumbersome, since it involves to deploy the MAF JavaScript files on the remote server. We aim to make this much easier in a forthcoming release of MAF.  The screenshot below shows an APEX page, which uses APEX's standard mobile template, referenced as a remote URL feature in a MAF application.  You can see the MAF navigation bar displayed at the bottom of the screen. On the other hand, MAF applications now use the new Oracle Alta UI skin by default. This means their appearance is very different from the standard APEX look and feel. Here is a capture of an AMX page from another feature in the same application.  The logical conclusion is that the transition between local and remote content will be transparent to the end user if you use consistent styling. This will be easier to achieve once APEX 5 will be available. Exposing PL/SQL logic as web services MAF applications usually fetch data and initiate business transactions through web service calls, although they can interact with the local SQLite database when in offline mode. Your current APEX applications probably contain queries and PL/SQL logic you could reuse in that context. MAF supports the two dominant web service styles: SOAP and RESTFul. Each style has its own pros and cons. SOAP, being the oldest of the two, provides broad standardization and interoperability. It also supports several protocols, such as HTTP, SMTP and JMS. In addition, SOAP offers many enterprise-grade features, such as reliable messaging.  On the other hand, SOAP based implementation are usually slower and consume more resources since the messages exchanged are in XML. RESTFul style services do not suffer from that problem, since they rather rely on lightweight data encodings such as JSON (JavaScript Object Notation). This probably explains the growing popularity of the RESTFul style, even if it only supports the HTTP protocol.   RESTFul services will be at the core of the upcoming Oracle Mobile Cloud service, by the way.  There are at least four different ways to expose SQL queries and PL/SQL logic as web services. Those are: RESTFul enabled report regions in APEX APEX REST Service Modules XMLDB native web services TopLink DB Web Service Provider APEX itself offers two different ways to expose REST web services; both require the use of the Oracle REST Data Services component, formerly known as the Oracle APEX Listener. REST Data Services is a Java Enterprise Edition (JEE) application deployed on WebLogic, GlassFish, or any JEE-compliant server. The two other web servers supported by APEX, namely the Embedded PL/SQL Gateway and the Oracle HTTP server (with mod_plsql), do not support REST web services.  RESTFul enabled report regions are simple to deploy and reuse existing assets directly. However, they are read-only and developers do not have control over the URL used. Furthermore, parameters are limited to scalar values since they are passed as a CSV string.  As you can see, RESTFul enabled report regions have many downsides. Fortunately, APEX’s REST Service Modules bring much more to the table, albeit at the cost of added complexity. A service module is essentially a set of URI resource templates. Each module defines a top level URI (like /store for example) and each template is a path branching out from the module’s URI (ex: /store/order). Templates contain at least one handler – but at most one for each HTTP method. A handler is simply the SQL query or anonymous PL/SQL block to execute; it can define parameters and specify the expected input type as well as the response format (JSON or CSV). APEX service modules are very flexible. They support all HTTP methods, give developers full control over the URL, can work with complex parameters and offer a comprehensive array of security features, such as single sign-on and security token support. Curiously, they miss the XML output option found in RESTFul enabled report regions. Also, you will have to look elsewhere if you need to expose SOAP service interfaces. APEX service modules are REST only for the time being. The user interface provided by APEX to manage service modules, shown in the following screenshot, is both powerful and easy to use. It enables developers to test their services right in their browser and is fully integrated with the rest of the APEX user interface. If you wish to build SOAP style web services directly on the top of the Oracle Database, you will have to leverage the XML DB Native Web Services feature. To achieve this, the Oracle XML DB HTTP server must be up and running. Your server already fulfills this requirement if you installed APEX on it. Then, you must as the SYS user and configure a specific servlet, whose name is usually « orawsv ».  XML DB Native web services can execute arbitrary SQL queries received as XML and give access to PL/SQL stored procedures as well. In both cases, the database will generate the required WSDL files. As you can see, XML DB native web services are a simple and effective way to expose existing PL/SQL code, although they cannot provide RESTFul service interfaces. Do not forget, however, that a proper service layer must encapsulate the complexity of the underlying application. Consequently, you shouldn’t let service consumers access the packages containing the logic of your APEX application. My recommendation is to create a package to act as the web service interface; the body of this package will simply wrap the procedures and functions meant to be available through the web service. This will obviously require some work. In addition, you need to be careful about the rights granted to the database account assigned to the web services. The fact that XML DB can run arbitrary queries sent as XML messages is a security risk that must be mitigated. An alternate way to build SOAP web services is to use the Oracle TopLink DB Web Service Provider. Both Oracle JDeveloper and Oracle Enterprise Pack for Eclipse (OEPE) provide tooling for it. The provider can expose web services based on PL/SQL code and SQL queries; it can also generate a CRUD API for any database table. The resulting Java application, which contains little to no code, can be deployed on any JEE compliant application server. This obviously lessens the load on the database server, which can lead to improved performance and scalability. On the other hand, this solution necessitates additional infrastructure; however, you need an application server anyway to host Oracle REST Data Services. The TopLink DB Web Service Provider also works with non-Oracle databases, making it an attractive solution if you want to standardize on a single tool in heterogeneous environments. Moreover, TopLink makes it easy to build RESTFul web services, although doing so will require more code than simply using the provider. This is somewhat mitigated by the fact that TopLink can generate the artifacts it needs from an existing database schema.  Conclusion APEX cannot produce on-device applications with offline capabilities. This doesn't mean you should leave it behind, quite the contrary. Oracle MAF applications can easily integrate web pages built with APEX. In addition, there are several ways to expose PL/SQL logic as SOAP or REST web services. Thus, adopting MAF on the client side simply consolidates your investments in APEX and PL/SQL on the server side. In the mobile space, APEX and MAF do not compete with each other and are, truly, better together. And the future is even brighter! If IDE-based development is not your cup of tea, you should be soon be able to develop MAF applications in the Cloud, using only a browser...  

For more than 10 years, PL/SQL developers have used Oracle Application Express (APEX) to deliver high quality applications quickly and efficiently. In the last few releases, the product has gained...

ADF

Mobile and Social login connections in Oracle MAF: a few hints to install the server-side components

Of all the new security-related features introduced in the Oracle Mobile Application Framework, the most interesting ones are in my opinion support for the OAuth 2.0 protocol and the tight integration to Oracle's identity management solutions. The former enables you to build MAF applications that will integrate with popular public APIs, such as the ones offered by Google and Facebook. The latter makes the implementation of comprehensive access control scenarios significantly easier, while keeping things extremely simple in a developer perspective. This is all thanks to the Oracle Access Management Mobile and Social (OAMMS) component of IDM. Don't believe me? Have a look at this recording I made for the Oracle Mobile Platform channel on YouTube.  If you want to try OAMMS for yourself, you will need to install it in your own environment. Overall, the process is fairly painless and is similar to other Fusion Middleware products. However, there are a few things should be aware of. Here are a few hints to guide you along the way. You need at least IDM 11gR2 PS2In other words,  MAF is certified with OAMMS 11.1.2.2 or later. Ensure you download the correct version!  Use JDK 7Java 8 has been with us for more than a year now. Public updates for Java 6, on the other hand, have stopped back in... 2011. If you were installing a production server today, I would strongly recommend you to use Java 7. Oracle WebLogic Server 10.3.6 is certified for use with Java 7 on Windows, Linux and other platforms. The official documentation explains at length how to use both together. The critical part is to ensure to override some of the standard JDK classes with ones provided with Weblogic:After installing WebLogic Server, copy the following files from WL_HOME/modules to JAVA_HOME/jre/lib/endorsed, where WL_HOME is the WebLogic Server installation home directory: javax.annotation_1.0.0.0_1-0.jar, javax.xml.bind_2.1.1.jar and javax.xml.ws_2.1.1.jar Install both OAM and OAMMSTechnically, OAMMS can be installed in standalone mode. However, you will get a much more useful setup if you deploy it alongside OAM, since you will gain the capacity to configure SSO for web service calls and remote URL access. In addition, OAMMS is already preconfigured to use OAM for authentication when you install both at the same time.I do not recommend to install Oracle Adaptive Access Manager (OAAM) if you are building  a development environment. Some of the features of the product, such as IP address geolocation, require third party dependencies that cannot be obtained for free.  Don't forget to configure the security storeOnce the software has been installed, it is essential to perform an additional configuration process for the database security store. For a brand new install, you should execute the command shown below. In this case, WebLogic was installed in /oracle/wls1036, the IDM binaries were in /oracle/wls1036/Oracle_IDM1 and I had created a domain named idmps2. The value for the -p parameter is the password for the OPSS schema you created using the Repository Creation Utility (RCU) before installing the IDM software. /oracle/wls1036/oracle_common/common/bin/wlst.sh /oracle/wls1036/Oracle_IDM1/common/tools/configureSecurityStore.py -d /oracle/wls1036/user_projects/domains/idmps2/ -c IAM -p oracle -m create  Upgrade the OPSS schemaAnother thing you need to do before starting your OAMMS WebLogic domain for the first time is to update the OPSS schema using the patch set assistant. This is necessary to ensure that the versions for the database and the binaries are in sync. Install the most recent Identity Management Suite Bundle PatchFinally, it is essential to deploy the latest bundle patch for the product. At the time of writing, this was patch 18662903. The patch corrects an important problem in the user interface for the OAuth authentication service, among other things. This install is done trough OPatch, by the way. The necessary executable is installed alongside the IDM binaries; you do not need to have your own OPatch installation.  Once you are done, you will need to configure OAMMS properly before your MAF applications can authenticate against it. Fortunately, you can learn about what you need to do on YouTube. 

Of all the new security-related features introduced in the Oracle Mobile Application Framework, the most interesting ones are in my opinion support for the OAuth 2.0 protocol and the tight integration...

ADF

JDeveloper 12.1.3 is good news for Maven fans

JDeveloper 12c 12.1.3 is finally available. The list of new features and enhancements is quite impressive. Have a look! You will not be disappointed. Personally, I was very happy to discover than Apache Maven support has been enhanced in two small but critical areas: paths and archetypes. Don't get me wrong: Maven support in 12.1.2 is leaps and bounds ahead what 11g offers. But the tweaks brought in 12.1.3 make a significant difference.  The main issue with the Maven support in 12.1.2 is that the POM files generated by JDeveloper contain absolute paths. This is problematic, since applications will not compile correctly unless the code resides in the same location on all developer workstations and build servers. This is not always possible or even desirable. Thus, I described how to replace those absolute paths with relative ones in a previous blog post. Fortunately, JDeveloper 12.1.3 does things differently and writes its POMs with relative paths instead.  Maven archetypes help developers create new applications from scratch  from the command line. It is now possible to build a new ADF application that way using the oracle-adffaces-ejb archetype introduced by Oracle in JDeveloper 12.1.3. The resulting application will use EJB for its model layer. To use the archetype, simply issue a command like the one below: mvn archetype:generate -DarchetypeGroupId=com.oracle.adf.archetype -DarchetypeArtifactId=oracle-adffaces-ejb -DarchetypeVersion=12.1.3-0-0 -DgroupId=oracle.test -DartifactId=my-maven-test -Dversion=1.0-SNAPSHOT  Obviously, this command will be successful only if the Maven binaries directory has been added to the path. Remember that Maven is provided by JDeveloper and can be found in the ORACLE_HOME/oracle_common/modules directory - although you can use your own install instead.  If you prefer to use a GUI, you can create an application from inside JDeveloper by using a little known option introduced in 12.1.2. First, open the New... gallery and select the Maven subcategory (under the General category). Then, select the Generate from Archetype item. This will bring up the dialog shown below. Fill the various values per Maven conventions. The application top level directory will be created under the directory you specify. To select the archetype to use, click on the looking glass besides the Maven archetype field. JDeveloper will then display the Search for Archetypes dialog. To use it, simply type a search string and press Enter. JDeveloper will list all the matching archetypes available for the repositories selected. Simply select the appropriate archetype and click on OK to create the new application.  Depending how your environment has been setup, it is possible that your local Maven repository doesn't contain an archetype catalog. If that's the case, the Local Repository option will be grayed out in the Search for Archetypes dialog. To fix this, execute the command below.  mvn archetype:crawl -Dcatalog=<maven directory folder>/archetype-catalog.xml  On Linux and OS X, the local repository is usually found at $HOME/.m2.  On Windows, the default location is %HOMEDRIVE%%HOMEPATH%/.m2. 

JDeveloper 12c 12.1.3 is finally available. The list of new features and enhancements is quite impressive. Have a look! You will not be disappointed. Personally, I was very happy to discover than...

ADF

ADF Mobile: the Access Control Service

ADF Mobile applications use standard HTTP mechanisms for authentication.  The HTTP protocol, however, does not handle authorization. Thus, to enable applications to obtain the roles and privileges of a specific user,  you need to implement a REST web service called the Access Control Service. In this post, I will show you how to implement the foundations for that service.  The product documentation states that the Access Control Service consumes and produces JSON data. The snippet below illustrates how parameters are passed to the service.  {"userId": "johnsmith","filterMask": ["role", "privilege"],"roleFilter": [ "role1", "role2" ],"privilegeFilter": ["priv1", "priv2", "priv3"] } All parameters other than userId are optional. FilterMask is used to specify which filters should be applied to the request (role, privilege or both). RoleFilter and privilegeFilter simply enumerate the filter values. If no filters are specified, the web service should return the list of all roles and privileges for the user. Otherwise, the service should only verify if the user belongs to the roles listed in roleFilter and if he has been granted the privileges listed in privilegeFilter. The ADF Mobile documentation gives the JSON snippet below as an example of a service response. {"userId": "johnsmith","roles": [ "role1" ],"privileges": ["priv1", "priv3"] } As you can see, the service returns only the roles and privileges that actually apply to the user.  The easiest way to implement the service is to take advantage of the POJO mapping feature offered by some JAX-RS implementations, such as Jersey. The first step is to build POJO class definitions for the service request and response. JDeveloper made this very easy. I only had to type a few lines of code for the class attributes and generated the accessors and constructors.  This is the code for the request class.  package oracle.sample.maf.accesscontrol.bo;import javax.xml.bind.annotation.XmlRootElement;@XmlRootElementpublic class ACSRequest { private String userId;private String[] filterMask;private String[] roleFilter;private String[] privilegeFilter;public ACSRequest() {super();}public ACSRequest(String userId, String[] filterMask, String[] roleFilter, String[] privilegeFilter) {super();this.userId = userId;this.filterMask = filterMask;this.roleFilter = roleFilter;this.privilegeFilter = privilegeFilter;}public void setUserId(String userId) {this.userId = userId;}public String getUserId() {return userId;}public void setFilterMask(String[] filterMask) {this.filterMask = filterMask;}public String[] getFilterMask() {return filterMask;}public void setRoleFilter(String[] roleFilter) {this.roleFilter = roleFilter;}public String[] getRoleFilter() {return roleFilter;}public void setPrivilegeFilter(String[] privilegeFilter) {this.privilegeFilter = privilegeFilter;}public String[] getPrivilegeFilter() {return privilegeFilter;}} The @XmlRootElement annotation makes it very easy to generate both JSON and XML from a single set of objects; I added it to the class even though it wasn't necessary in this specific use case. The code for the response class is straightforward.   package oracle.sample.maf.accesscontrol.bo;import javax.xml.bind.annotation.XmlRootElement;@XmlRootElementpublic class ACSResponse { private String userId;private String[] roles;private String[] privileges; public ACSResponse() {super(); roles = new String[0]; privileges = new String[0];} public ACSResponse(String p_userId, String[] p_roles, String[] p_privileges) {super(); userId = p_userId; roles = p_roles; privileges = p_privileges;} public String getUserId(){return userId;} public void setUserId(String p_id){ userId = p_id;} public String[] getRoles(){return roles;} public void setRoles(String[] p_roles){ roles = p_roles;}public String[] getPrivileges(){return privileges;} public void setPrivileges(String[] p_privileges){ roles = p_privileges;}} By default, POJO mapping is not enabled in Jersey. It is thus essential to add the following init parameter to the Jersey servlet declaration in the web.xml for the application. <init-param><param-name>com.sun.jersey.api.json.POJOMappingFeature</param-name><param-value>true</param-value></init-param> The service itself is implemented as yet another POJO. I generated a skeleton for the class using the REST web service wizard in JDeveloper. The method that will process the request must be configured to process requests made using the POST HTTP verb. Hence, the single method in the class is annotated with @POST. 1 2 3 4 5 6 7 8 91011121314151617181920212223242526272829 package oracle.sample.maf.accesscontrol.service;import javax.ws.rs.Consumes;import javax.ws.rs.POST;import javax.ws.rs.Path;import javax.ws.rs.Produces;import javax.ws.rs.core.Response;import oracle.sample.maf.accesscontrol.bo.ACSRequest;import oracle.sample.maf.accesscontrol.bo.ACSResponse;@Path("user")@Consumes("application/json")@Produces("application/json")public class UserRessource {public UserRessource() {}@POSTpublic Response postData(ACSRequest request) { // Replace this with actual logic. ACSResponse rolesAndPrivileges = new ACSResponse(request.getUserId(), new String[] { "user" }, new String[] { "user" }); Response.ResponseBuilder builder = Response.ok(rolesAndPrivileges);return builder.build();}} The @Path annotation on line 12 determines the path to the REST resource, whereas @Consumes and @Produces specify the expected data formats for the method's input and output.  The sample class above doesn't contain error handling code and returns a hard coded response. A production implementation should use the various static methods in javax.ws.rs.core.Response to build responses. The ok(Object) method will typically be used; other methods such as noContent(), notAcceptable(List) and serverError() will be called instead when specific conditions are met or if exceptions have been raised.  There are many ways to obtain the data needed to populate the response. You could query a database, for example, or use the OPSS APIs to query an LDAP server. Whatever option you choose, your service implementation should ensure that users cannot query another user's roles and privileges unless they have administrative privileges themselves. In other words: exposing on the internet a web service which enables anybody to identify privileged user accounts for your back-end is a bad idea. Ideally, your service should: Accept connections over HTTPS only Check that the credentials used to establish the SSL / TLS connection match the userId in the service input - unless the user can manipulate the roles and privileges of other users The Access Control service is an essential component of the ADF Mobile architecture. Since Oracle only specifies the service signature, you can implement it in the way that best fits your infrastructure and the level of authorization granularity you expect.  

ADF Mobile applications use standard HTTP mechanisms for authentication.  The HTTP protocol, however, does not handle authorization. Thus, to enable applications to obtain the roles and privileges of...

ADF

Sometimes a new skin is not enough

I often have the opportunity to present about Oracle's mobile technologies. In those presentations, I usually explain to the audience that building and maintaining a mobile application will force them to make their software development processes more agile. The reason for this is simple. Mobile technologies evolve at consumer speed. Mobile operating systems are updated frequently, and applications must follow suit. The best proof I can give is the evolution of ADF Mobile itself. The initial version of the framework has been released in October 2012. Between that date and January 2014, we published one new version and five distinct patch sets for it; that's one update every 11 weeks on average. Such frequent releases are unusual for Oracle. In the mobile space, they're the norm Recently, I installed ADF Mobile Patch 5. This version includes a new skin which brings an iOS 7 look and feel for Apple devices as well as a native look and feel for Android devices. In addition, JDeveloper now supports version 5 of XCode to package and deploy iOS applications. After the update, my applications didn't look right when I deployed and ran them. It turns out you must update the skin-family in adfmf-config.xml from this <skin-family>mobileFusionFX</skin-family> to this <skin-family>mobileAlta</skin-family> In addition, I suggest you perform a clean all (Build > Clean All) before deploying your applications. Mine would not pick up the new skin otherwise. 

I often have the opportunity to present about Oracle's mobile technologies. In those presentations, I usually explain to the audience that building and maintaining a mobile application will force them...

ADF

Picking up the threads in ADF Mobile

There is a huge difference between the actual performance of an application and the user's perception of that performance. Typically, developers will try to improve the latter by delegating time-consuming tasks to background threads; in other words: asynchronous processing makes it possible to keep the user interface responsive at all times. This is especially important in mobile applications, where network bandwidth and latency can fluctuate wildly in a short time frame. Users are not necessarily aware of changes in network conditions, and thus will readily ascribe any slowdown to the application itself. Consequently, multithreaded programming is an essential part of the mobile developer's tool set. ADF Mobile applications run on a Java virtual machine. Therefore, they can start threads that will exist in the context of the JVM process. In the current release, the ADF Mobile JVM follows the JavaME CDC specification, which is based on Java 1.4. This means that, unfortunately, the improvements brought by JSR 166 (java.util.concurrent)  are not available. On the other hand, threads are well integrated in the ADF Mobile framework. They can invoke AdfmfJavaUtilities.invokeDataControlMethod or AdfmfJavaUtilities.setELValue, for example. This makes it possible for you to update the user interface or refresh a bound collection in memory from a thread among other things. The Apple iOS and Google Android operating systems manage application-related resources themselves. In iOS, when you switch to another application, the current application is suspended. On the other hand, Android's behavior in the same scenario will vary depending on the free memory available on the device. Typically, the processes belonging to an application will continue to run in the background after the switch; when memory is scarce, the operating system may force-kill the process. What happens when you switch away from an ADF Mobile application is thus dependent on the underlying OS. Any threads started by the application process will behave in the same way as the process itself.  By default, threads will suspend and resume by themselves on iOS; they will still run in the background on Android.  If you want to implement multithreading in your application, my recommendation is to always manage the state of your threads explicitly and to interrupt them when the application is deactivated or suspended. This will ensure the integrity of your data and will make the application behave the same way independently of the operating system. Interrupting a thread is done by calling the interrupt() method of the Thread class and by checking the return values of the interrupted() or isInterrupted() methods inside the run() method of the thread or of the runnable.  The proper location for the call to interrupt() is a listener class implementing the oracle.adfmf.application.LifeCycleListener interface; such listeners must be registered in  adfmf-application.xml. The activate() and deactivate() methods it specifies will be invoked even if the application is killed through the Android task manager. Typically, in addition to interrupt the threads, the application will need to do the following in order to ensure a proper deactivation: Write any restorable state to an appropriate store Close database cursors and connections Defer pending web service requests Release resources such as files These tasks can be performed by the threads themselves, by their associated java.lang.Runnable instances, or somewhere else. Be careful, though, since activate() and deactivate()will not be called if the application is terminated. It is also possible to implement listeners at the feature level if more granularity is needed. Such listeners implement the oracle.adfmf.feature.LifeCycleListener interface instead. Please note calls to activate() and deactivate() are blocking; you will need to be careful to ensure the application doesn't look unresponsive to the user. Resource contention is without a doubt one of the greatest challenges any multithreaded application must solve. In ADF Mobile, each local database corresponds to a single file; the SQLite database engine thus implements a complex but reliable locking system.  Fortunately, ADF Mobile encapsulates all the complexity. If two threads - each possessing its own JDBC connection to the database - try to write at the same time, no exception will be thrown. One of the threads will own the write lock and will be able to proceed, while the other will wait. In other words: there can be only one database connection in write mode at any given time. All other connections will be in read-only mode until they can acquire the write lock. This will influence the design of your application. For example: if you have to insert a sizable number of records in a background thread, you will perform the operation in smaller batches in order to yield the lock to other threads of higher priority.  Writing a good application is not easy, nor is writing a good performing one.  Multithreading can help with the latter, but you must be careful not to waste resources when the application is not in the foreground. After all, performance is not the only component in the user's perception of your application; battery life counts as well... 

There is a huge difference between the actual performance of an application and the user's perception of that performance. Typically, developers will try to improve the latter by delegating...

Infrastructure

Put your VirtualBox VMs on a diet

One of the nice things with Oracle VM VirtualBox is that you don't need to allocate all the disk space in advance. It is possible, say, to give a 60 Gb hard drive to a virtual machine but have an actual footprint much lower than that by creating the hard drive in dynamically allocated storage mode. Basically, this means the actual size for the hard drive will match the size of the files it contains. The footprint will grow over time, as you add files. Unfortunately, this is a one way process. The virtual hard drive will take more space on disk as it grows, but will not release the space if it shrinks. This can be a problem, for example, if you copied several Fusion Middleware installers on the VM and want to recuperate that space after installation.  I am currently playing with VMs a lot, and found a way to get the space back. This is a two step process. The first step is to fill the empty space with zeroes. There are utilities for that on Windows and OS X, but you can do it very easily on the command line on Oracle Enterprise Linux. Simply execute the following commands inside the virtual machine as root (or prefix with sudo): dd if=/dev/zero of=/hugeemptyfile bs=4096krm -rf /hugeemptyfile  Obviously, you should close all other programs before doing this, and ensure no background process will require disk space while dd is running. Once this is done, shut down the VM and open a command line on the host machine. Go to the folder where VirtualBox is installed, and type something like this, substituting the correct path and file name for the virtual hard drive: VBoxManage modifyhd "V:\VirtualBox VMs\Oracle\Oracle.vdi" -compact  After a few minutes, you will get the wasted space back. VirtualBox, by the way, has an extensive collection of command line utilities. You can even run a VM without opening the VirtualBox GUI using the VBoxHeadless command, for example. Also: did you know it is possible to start a VM in headless mode from the GUI? Simply press shift at the same time you click on the start button. 

One of the nice things with Oracle VM VirtualBox is that you don't need to allocate all the disk space in advance. It is possible, say, to give a 60 Gb hard drive to a virtual machine but have an...

ADF

Juggling with JDKs on Apple OS X

I recently got a shiny new MacBook Pro to help me support our ADF Mobile customers. It is really a wonderful piece of hardware, although I am still adjusting to Apple's peculiar keyboard layout. Did you know, for example, that the « delete » key actually performs a « backspace »? But I disgress... As you may know, ADF Mobile development still requires JDeveloper 11gR2, which in turn runs on Java 6. On the other hand, JDeveloper 12c needs JDK 7. I wanted to install both versions, and wasn't sure how to do it.   If you remember, I explained in a previous blog entry how to install JDeveloper 11gR2 on Apple's OS X. The trick was to use the /usr/libexec/java_home command in order to invoke the proper JDK. In this case, I could have done the same thing; the two JDKs can coexist without any problems, since they install in completely different locations. But I wanted more than just installing JDeveloper. I wanted to be able to select my JDK when using the command line as well. On Windows, this is easy, since I keep all my JDKs in a central location. I simply have to move to the appropriate folder or type the folder name in the command I want to execute. Problem is, on OS X, the paths to the JDKs are... let's say convoluted.  Here is the one for Java 6. /System/Library/Java/JavaVirtualMachines/1.6.0.jdk/Contents/Home The Java 7 path is not better, just different. /Library/Java/JavaVirtualMachines/jdk1.7.0_45.jdk/Contents/Home Intuitive, isn't it? Clearly, I needed something better... On OS X, the default command shell is bash. It is possible to configure the shell environment by creating a file named « .profile » in a user's home folder. Thus, I created such a file and put the following inside: export JAVA_7_HOME=$(/usr/libexec/java_home -v1.7)export JAVA_6_HOME=$(/usr/libexec/java_home -v1.6)export JAVA_HOME=$JAVA_7_HOMEalias java6='export JAVA_HOME=$JAVA_6_HOME'alias java7='export JAVA_HOME=$JAVA_7_HOME'  The first two lines retrieve the current paths for Java 7 and Java 6 and store them in two environment variables. The third line marks Java 7 as the default. The last two lines create command aliases. Thus, when I type java6, the value for JAVA_HOME is set to JAVA_6_HOME, for example.  I now have an environment which works even better than the one I have on Windows, since I can change my active JDK on a whim. Here a sample, fresh from my terminal window. fdesbien-mac:~ fdesbien$ java6fdesbien-mac:~ fdesbien$ java -versionjava version "1.6.0_65"Java(TM) SE Runtime Environment (build 1.6.0_65-b14-462-11M4609)Java HotSpot(TM) 64-Bit Server VM (build 20.65-b04-462, mixed mode)fdesbien-mac:~ fdesbien$ fdesbien-mac:~ fdesbien$ java7fdesbien-mac:~ fdesbien$ java -versionjava version "1.7.0_45"Java(TM) SE Runtime Environment (build 1.7.0_45-b18)Java HotSpot(TM) 64-Bit Server VM (build 24.45-b08, mixed mode)fdesbien-mac:~ fdesbien$ Et voilà! Maximum flexibility without downsides, just I like it. 

I recently got a shiny new MacBook Pro to help me support our ADF Mobile customers. It is really a wonderful piece of hardware, although I am still adjusting to Apple's peculiar keyboard layout. Did...

ADF

ADF at 12c: time to get the facts straight

The 12c release is a major milestone both for ADF and JDeveloper. Most of you already know how strategic ADF is to Oracle; day after day, thousands of our own developers use it to build Fusion Applications, Enterprise Manager, SOA Suite and WebCenter among others. What is not readily apparent is how much maturity there is in the framework. The roots of ADF can be traced back to 1999, when the first release of Java Business Objects (JBO) was made available. The ancestor of today's ADF Faces components, User Interface XML (UIX), has been introduced in 2002. More than ten years later, ADF is still going strong and the best is yet to come. I have been developing with ADF since 2007. Since then, I often had the opportunity to introduce new developers to it. While I was often greeted with skepticism, the natural qualities of the framework and the productivity brought by JDeveloper usually won minds if not hearts. I saw this once again at OpenWorld 2013. Obviously, ADF is not perfect and there are several worthy alternatives in the market. But what surprises me is that many of the objections made against ADF stem from misconceptions - even after all those years. Here are five of the most common ones: ADF is not open. ADF is just for huge enterprise applications. ADF is proprietary. ADF is tied to JDeveloper,  Weblogic and Oracle Database. ADF is expensive. My aim in this post is to get the facts straight. Let's discuss each of them. ADF is not open This is something I heard frequently. But what does « open » mean? Is it about access to the source code? About technical interoperability? Maybe about stewardship? Customers covered by a valid support contract can request access to the ADF source code. Not only that, but some of its components have been released under open-source licenses, the most significant being Apache MyFaces Trinidad. And since ADF is built on the top of Java Enterprise Edition, it integrates with other solutions running on the platform. True, Oracle keeps full control over strategic orientations and new features. But our company is making significant efforts to better address the concerns of the community. The ADF Enterprise Methodology Group, for example, is a great forum to propose and discuss new features. We follow closely what is posted there and will never hesitate to open enhancements requests if needed. ADF is just for huge enterprise applications This is a funny one, and probably comes from the fact that ADF is based on Java. Yet, small and simple applications are a cinch to implement with the framework; it focuses on productivity first. Lots of people forget that ADF favors a code last approach. In other words: most ADF artifacts can be implemented declaratively rather than through code. In addition, most of the time, developers will build the user interface simply by drag and dropping attributes from the data controls palette. Moreover, ADF puts great emphasis on reuse. Entity Objects, View Objects, Task Flows and Page Fragments are inherently reusable. You can push this even further by using page fragments, JSF templates and declarative components. Thus, you can reduce the actual size of your applications by sharing code extensively between applications. It is also essential to remember that ADF implements several common software patterns, such as Model-View-Controller, for you. This results in a little more complexity, but ensures that even the smallest of your applications adhere to industry best practices.  ADF is proprietary ADF is certainly unique to Oracle. In fact, it represents one of our biggest competitive advantages in the marketplace. Yet, some people conveniently forget it is a superset of Java Enterprise Edition first and foremost. ADF Faces, for example, is probably the most comprehensive set of JSF components available right now; the Data Visualization components now render to HTML 5 instead of Flash. On the other hand, ADF offers extensive support for the SOAP protocol and the WS-* extensions, which are industry standards. Yes, ADF deviates from JEE in some cases - but typically this is because it was ahead of the curve. ADF BC is rooted in JBO, a technology introduced in 1999. EJBs didn't deliver the performance and features required by developers at the time. In 2008, ADF Controller and Task Flows brought more flexibility than the standard JSF controller - which finally caught up in 2013 in JEE 7. We even make it possible to use EJB or JPA to implement business logic if you prefer them to ADF BC.  Moving forward, you can expect ADF to integrate many more standards, but not at the cost of innovation. ADF is tied to JDeveloper,  Weblogic and Oracle Database This one was true a few years ago. Nowadays, you can build ADF applications in Eclipse by installing the Oracle Enterprise Pack for Eclipse plugins. You can use almost any SQL92-compliant database with ADF, and we even offer optimizations specific to IBM DB2 and Microsoft SQL Server. Best of all, we offer integration to various Application Lifecycle Management platforms in JDeveloper and OEPE, but are not offering one ourselves. You get to choose the tools you prefer to support your development process. And with the free ADF Essentials, you can deploy your ADF applications to nearly all containers implementing the Java Enterprise Edition web profile. GlassFish server is an obvious choice here, but old favorites like Apache Tomcat and JBoss can be used too.  ADF is expensive No, it's not. For a long time, ADF has been merely inexpensive as it was bundled with WebLogic Server. With ADF Essentials, the core features are free; the features cut from from it are essentially hooks to other Fusion Middleware products. The developer tools, by the way, are completely free. You cannot really appreciate that fact unless you had to pay for multiple IDE licenses for your team, something I had to do earlier in my carrier when I was building software for IBM and Microsoft platforms.  Conclusion ADF 12c is there. And it's here to stay. Maybe you should consider it...

The 12c release is a major milestone both for ADF and JDeveloper. Most of you already know how strategic ADF is to Oracle; day after day, thousands of our own developers use it to build...

ADF

JDeveloper 12c and Maven: Using relative paths in your POM files

One of the greatest things about JDeveloper 12c is the significantly improved support for Apache Maven. By default, the POM files produced by my favorite IDE contain some absolute paths, such as the folder for the ojmake/ojdeploy executables and references to project (.jpr) and application (.jws) files. Here is a sample of such paths extracted from an application I created on a Windows machine. 1 2 3 4 5 6 7 8 9101112131415161718192021222324 <plugin><groupId>com.oracle.adf.plugin</groupId><artifactId>ojmake</artifactId><version>12.1.2-0-0</version><configuration><ojmake> C:\Oracle\Middleware1212\jdeveloper\jdev\bin\ojmake.exe</ojmake><files> C:\OracleData\JDEV_USER_DIR\mywork\MavenTest\Model\Model.jpr</files><usemaven> true</usemaven></configuration><executions><execution><phase>compile</phase><goals><goal>compile</goal></goals></execution></executions></plugin> This is perfectly fine if your development team uses workstations that are configured in a consistent way and run under the same operating system. It is often not the case in the real world. Fortunately, Maven provides features that make it very easy to use relative paths instead. The first thing you should know is that Maven supports the use of variables in POM files. Those variables are always referenced using the following syntax: ${variable_name} There are several built-in variables provided by Maven. One of them is ${basedir}, which points to the folder where the current POM is located. In addition, Maven can access any environment variable defined by the operating system. This is achieved though the following syntax: ${env.variable_name}  Thus, it is possible to remove all absolute paths from the sample above by using ${basedir} and referencing an environment variable. Suppose I created such a variable named OJ_HOME, which points to  C:\Oracle\Middleware1212\jdeveloper\jdev\bin. Then, the POM would look like this: 1 2 3 4 5 6 7 8 9101112131415161718192021222324 <plugin><groupId>com.oracle.adf.plugin</groupId><artifactId>ojmake</artifactId><version>12.1.2-0-0</version><configuration><ojmake> ${env.OJ_HOME}\ojmake.exe</ojmake><files> ${basedir}\ViewController.jpr</files><usemaven> true</usemaven></configuration><executions><execution><phase>compile</phase><goals><goal>compile</goal></goals></execution></executions></plugin> This POM will run on any workstation, granted the OJ_HOME variable is set to a suitable value.

One of the greatest things about JDeveloper 12c is the significantly improved support for Apache Maven. By default, the POM files produced by my favorite IDE contain some absolute paths, such as the...

ADF

Saved by the local database!

In my last post, I told you about my latest ADF Insider Essentials recording on the local database, and pointed you to the companion code sample. I had lots of feedback about both. I am glad to see I have so many viewers and readers! Among all the questions I got, one was asked very frequently: « How can I transparently retrieve data from the database when a web service call fails? » In other words: how can the local database save my life if the web service doesn't respond? This is a bit different from what I had implemented initially. Thus, I built a new version of the sample application which does exactly that. In the original sample, the code simply detected the presence or absence of a network connection; an available connection meant the web service call was assumed to succeed. Otherwise, an exception was raised and displayed to the user. Thus, the key change to obtain the desired behavior is simply to catch the exception. Then, it is easy to invoke the method that retrieves data from the database instead. Here is the relevant method in the sample application. 1 2 3 4 5 6 7 8 910111213141516171819202122232425262728 private CountryBO[] getCountriesFromWS() {try { GenericType genericReturnValue =(GenericType)AdfmfJavaUtilities.invokeDataControlMethod("HR_WS", null, "findCountry", new ArrayList(),new ArrayList(), new ArrayList()); CountryBO[] returnValue =(CountryBO[])GenericTypeBeanSerializationHelper.fromGenericType(CountryBO[].class, genericReturnValue,"result"); Arrays.sort(returnValue);return returnValue;} catch (AdfInvocationException aie) {if (AdfInvocationException.CATEGORY_WEBSERVICE.compareTo(aie.getErrorCategory()) == 0) { AdfmfContainerUtilities.invokeContainerJavaScriptFunction("oracle.adfinsider.localdb.countries","navigator.notification.alert",new Object[] { "The web service is unavailable. \n\n Data has been retrieved from the local cache.","null", "Warning", "Ok" });return getCountriesFromDB();} else {throw new RuntimeException(aie);}} catch (Exception ex) { Utility.ApplicationLogger.severe(ex.getMessage());throw new RuntimeException(ex);}} Another nice thing this code snippet demonstrates is how to call JavaScript code from Java business logic. At line 15, I invoke a method which is part of the Apache Cordova library to display a warning message to the user. Cordova is an integral component of ADF Mobile, but your AMX pages must be properly configured in order to use it. I added the proper references to the countriesList.amx page like this: 1 2 3 4 5 6 7 8 91011 <amx:panelPage id="pp1"><amx:verbatim id="v1"><script type="text/javascript">if (!window.adf) window.adf = {}; adf.wwwPath = "../../../../www/";</script> <script type="text/javascript" src="../../../../www/js/base.js"></script><script type="text/javascript" src="../../../../www/js/cordova-2.2.0.js"></script></amx:verbatim><amx:facet name="header"><amx:outputText value="#{viewcontrollerBundle.COUNTRIES}" id="ot1"/></amx:facet>...</amx:panelPage> I placed the script references (lines 3 to 5) inside a verbatim tag, which ensures that they will be rendered as is in the page. While I was at it, I fixed a few other issues with the sample. In the original version, the database connection was closed inside the stop() method of the LifeCycleListenerImpl class. The stop() method is usually called when the use exits the application; there is no guarantee, however. Thus, the connection wouldn't be closed properly in some corner cases. To fix this, I moved the code to the deactivate() method, which doesn't suffer from the same drawback and will be called each time the user switches to another application. This is much better, as the connection will be properly closed even if the device crashes while the application is inactive. You can download the refreshed sample application here. 

In my last post, I told you about my latest ADF Insider Essentials recording on the local database, and pointed you to the companion code sample. I had lots of feedback about both. I am glad to see I...

ADF

See the ADF Mobile local database in action

ADF Insider recordings are probable one of the best parts of my job. They are a lot of work, sure. But they are lots of fun to do and join so many members of the ADF Community...  My latest recording is on the ADF Mobile local database. In it, I explore the various aspect of the feature and devote a healthy chunk of time to the management of the database file. The slides contain a few selected code snippets, but I thought it would be better to build a sample application to fully illustrate the concepts. In particular, I wanted to show how it is possible to retrieve data from either a web service or the local database while binding the UI to a POJO Data Control.  My sample application  is made is made of two distinct components:     - A simple SOAP web service (SDO view object) built on the top of the HR database schema.     - The ADF Mobile application itself, that demonstrates local database techniques and calls the web service when a network is available. Data is fetched from the local database when their is no connectivity. I contributed the application to the ADF Enterprise Methodology Group samples repository. It is not listed on the web pages right now, but you can download it from the following location: https://svn.java.net/svn/smuenchadf~samples/ADFMobileLocalDatabase.zip My recording is available on our YouTube channel here: http://www.youtube.com/watch?v=-XzE1n_j5Nc. 

ADF Insider recordings are probable one of the best parts of my job. They are a lot of work, sure. But they are lots of fun to do and join so many members of the ADF Community...  My latest recording...

ADF

From Russia with Java: answering the most frequently asked questions

Last week, I had the wonderful opportunity to visit Moscow and meet fellow Java developers. I was one of the presenters at the JavaOne Russia 2013 conference, on April 23 and 24. There, I talked about ADF, ADF Mobile and even forms. I was even able to spare a few hours for sightseeing... When not presenting, I passed most of my time at the ADF Demo booth, where I fielded lots of interesting questions from attendees. Since some of these questions were asked quite frequently, I thought it would be interesting to answer them here. How do I get a license for ADF Mobile?Maybe you don't even need to buy anything! Isn't this great?ADF Mobile is bundled with ADF. Currently, there are two ways to license ADF: on its own or through a WebLogic Server license. If you buy named user licenses, you can distribute your ADF Mobile applications to those same users on the devices they own. On the other hand, you can distribute your applications to an unlimited number of users and devices if you buy a processor license. Thus, a processor license is your best bet if you plan to distribute your applications through the Apple and Google Play stores.If you hesitate between named user licenses and the processor license, the latter will be more advantageous if you have around 50 users or more. I am not in sales, and prices in your regions could affect the value equation so please check with a sales representative.  What is the difference between ADF, ADF Mobile and ADF Mobile Browser?Oracle Application Development Framework (ADF) is the toolkit at the core of Fusion Architecture. Through the ADF Faces set of components, it enables you to build rich and scalable web applications for desktop and high-end mobile devices (such as Apple's iPad), and can be used to build SOA backbones that will be accessed by Swing and JavaFX applications, among others. You can even integrate ADF back-ends in Microsoft Office through ADF Desktop Integration. ADF is built from the ground up for easy integration with the other components of Fusion Middleware, such as Oracle WebCenter and Oracle SOA Suite.Oracle ADF Mobile enables you to build Java applications that will run directly on most current iOS and Android devices. Its model and controller layers provide a developer experience very close to the ADF one. ADF Mobile applications can consume standards-based web services and work very well with ADF SOA back-ends.Oracle ADF Mobile Browser is a set of JSF components that you can use instead of the regular ADF Faces components to create web applications that target a wide variety of mobile devices. The pages produced will gracefully adapt to the device's capabilities in order to deliver the richest user experience possible. Oracle has got JDeveloper, Netbeans and Oracle Enterprise Pack for Eclipse. Why do you have so many IDEs?Exactly for the same reason your favorite car brand offers several models: because not everyone has got the same needs.Netbeans is the perfect complement to the GlassFish Application Server, which is the reference implementation for Java Enterprise Edition. Thus, it will be your IDE of choice if you want to benefit from the latest advances in that space. Moreover, Netbeans provides unparalleled tools for JavaFX applications. Oracle Enterprise Pack for Eclipse (OEPE), on the other hand, shows Oracle's commitment to the current market share leader in Java IDEs. Oracle has been a member of the Eclipse Foundation for a long time and contributes to at least ten distinct Eclipse subprojects. In the last few years, OEPE has added support for a number for Fusion Middleware technologies such as Oracle ADF. Thus, you can build Fusion Architecture applications using an IDE you already know and love.Finally, Oracle JDeveloper is the best development environment for building Fusion Architecture application. With deep support for both other Fusion Middleware products and Java Enterprise Edition technologies, it focuses on developer productivity. JDeveloper is heaviliy used internally at Oracle, especially by the Fusion Applications team. When will JDeveloper 12c be out?I wish I could tell you! Unfortunately, revenue recognition rules in the US prevent us to provide a better answer than « sometime this year ».  The product team is working very hard on it as I write this. 12c will be a very nice release, and the internal builds I used recently show great promise.  I hope you found my answers useful. During my flight back home, I got a fortune cookie with my meal. I got two prophecies and really hope they will come true...

Last week, I had the wonderful opportunity to visit Moscow and meet fellow Java developers. I was one of the presenters at the JavaOne Russia 2013 conference, on April 23 and 24. There, I talked about...

ADF

ADF Mobile and SDO: getting results

In my previous post, I explained how to make web service calls to SDO view objects exposed through a service-enabled application module. So far, so good. What I didn't explain is how you can access the return value of the service call if there is one. The answer is straightforward... once you figured it out.  Our starting point, once again, is JDeveloper's Data Control palette. As you can see,  the name of the return value is result. Consequently, one could be tempted to use GenericTypeBeanSerializationHelper to convert the value. And one would be right. Even better: you don't have to worry about the type name exposed by the data control as with input parameters. Here, I simply retrieve the results of the call in VisitResultBO, which is a simple POJO.  GenericType genericReturnValue = (GenericType)AdfmfJavaUtilities.invokeDataControlMethod("VisitsWS", null, "getVisit", namesList, paramsList, typesList);Object returnValue =GenericTypeBeanSerializationHelper.fromGenericType(VisitResultBO.class, genericReturnValue,"visit"); What makes it not obvious is that the fromGenericType method has got two signatures:  fromGenericType(java.lang.Class beanClass, GenericType gt)fromGenericType(java.lang.Class beanClass, GenericType gt, java.lang.String attributeName) For SDO web services, you absolutely need to use the second form and pass "result" as the value for attributeName. I must admit it took me some time to realize this. 

In my previous post, I explained how to make web service calls to SDO view objects exposed through a service-enabled application module. So far, so good. What I didn't explain is how you can access...

ADF

ADF Mobile and SDO: making the connection

One of the great difficulties in building a mobile application is building a strong web service back-end. If you are using ADF BC as your data access layer, service-enabled application modules are a compelling option. My good friend Frank Nimphius published an article in Oracle Magazine on that very topic, titled Consume Early; Consume Often.  In the perspective of an ADF Mobile application, the web service methods exposed by the SDO interfaces of ADF BC view objects are accessed through the web service data control. It is worth remembering that, at this point, SDO interfaces can be reached through the SOAP protocol only. Support for REST interactions is currently planned for ADF 12c. Fortunately, the WSDL description for the service is generated by JDeveloper. It is possible to bind directly your AMX pages to the web service data control. Shay Shmeltzer has posted a few blog entries where he uses this technique, even for calling web services with complex parameters. Some use cases, however, can be implemented more cleanly by calling the web service data control in Java code, which implies the page is bound to a bean or to a POJO-based data control. But how does one invoke the web service data control from code? The first step is to look at the structure for the data control. Suppose I want to call the createVisit method exposed by the VisitsWS data control. The method accepts a single input parameter of type java.lang.Object Calling the method with any random object will not work. The data control expects an object of a very specific type, with attributes matching its own definition. It is possible to determine the name of the type expected by the data control by hovering above the parameter with the mouse pointer, as shown in the screenshot below. VisitsWS.Types.createVisit.visit is not implemented through a Java class; it is a virtual type managed by the data control. In ADF Mobile, the web service data control, when operating over the SOAP protocol, requires parameters to be passed as instances of the oracle.adfmf.util.GenericType interface. The only way to instantiate such objects is to use the GenericTypeBeanSerializationHelper class provided by the framework.  This class will transform POJO instances to and from GenericType. Below is a  code sample that shows how to build the GenericType and  invoke the web service through the data control. Visit visit = new Visit();// Set attribute values for visit here.List namesList = new ArrayList(1);List paramsList = new ArrayList(1);List typesList = new ArrayList(1); GenericType gtVisit = GenericTypeBeanSerializationHelper.toGenericType("VisitsWS.Types.createVisit.visit", visit);namesList.add("visit");paramsList.add(gtVisit);typesList.add(Object.class);try {    AdfmfJavaUtilities.invokeDataControlMethod("VisitsWS", null, "createVisit", namesList, paramsList, typesList);} catch (AdfInvocationException ex) {    // If the web service is not available throw a nice exception    if (AdfInvocationException.CATEGORY_WEBSERVICE.compareTo(ex.getErrorCategory()) == 0) {        throw new RuntimeException("Error with the server. Please try later.");    }} There are a few things you should take into account when creating your POJO objects. The attributes must have the same name as the data control attribute they are mapped to.  The attributes must preferably be of type java.lang.String. Other types may work, but you may run into problems. When manipulating dates, it is essential to express them in the ISO-8601 format expected by the SOAP service layer. This can be achieved through the oracle.adfmf.misc.ISO8601DateTimeUtil class. If the service you invoke is based on a view object that contains attributes retrieved through a join that are marked as a reference, your POJO must declare these attributes as transient. This way, no values will be transmitted back to the server in the case of create and update operations. Failing to do so will raise a JBO exception on the server.   By the way, if you found this post interesting, one of the two presentations I will make at the ODTUG Kaleidoscope 2013 conference in June will show you how to build flexible and SOA-compliant back-ends using Oracle ADF. See you in New Orleans! 

One of the great difficulties in building a mobile application is building a strong web service back-end. If you are using ADF BC as your data access layer, service-enabled application modules are a...

ADF

ADF Mobile on BlackBerry 10: a failed but instructive experiment

With the release of their new handsets and operating system, Blackberry occupied lots of media space recently. This prompted me to have a deeper look at their platform and to experiment a bit in relation to ADF Mobile. You shouldn't read anything in this, by the way; my personal curiosity doesn't foreshadow Oracle's strategy.  The BlackBerry 10 OS, as you may know, is able to run most Android applications through a runtime which supports about 70% of Android's APIs. Just for the sake of it, I tried to repackage a very simple ADF Mobile application and deploy it on the BlackBerry 10 simulator. Deployment was successful, and I was even able to get past the splash screen. It is only then that the application failed with an error message stating « Network_ERR: XMLHttpRequest Exception 101 ». This application is self-contained and didn't call any web services, by the way. The root cause of the error was obviously something else. To be truthful, I expected the experiment to fail. The Android toolkit provided by BlackBerry contains an executable that scans APKs (packaged Android applications) for compatibility. When I ran it on my ADF Mobile APK, it flagged various minor problems (since we are using various hardware features) as well as a major issue: the presence of native code. You can see the full output below: Apk2Bar /Verifier version 1.5.1Research In Motion Ltd ? 2012 All rights reserved.[osname.apk]:(res/drawable-xhdpi/adfmf_icon.png) found an alternate icon with better size:impact=1[osname.apk]:(AndroidManifest.xml) uses-feature: android.hardware.camera:required minimal Tablet OS version=2.1:impact=2[osname.apk]:(AndroidManifest.xml) uses-feature: android.hardware.telephony:required minimal Tablet OS version=10.0.6:impact=2[osname.apk]:(AndroidManifest.xml) uses-feature: android.hardware.camera.autofocus:required minimal Tablet OS version=10.0.9:impact=2[osname.apk]:(AndroidManifest.xml) native-code: armeabi:impact=5[osname.apk]:(com/phonegap/AudioHandler.java:275) uses method: android.media.AudioManager$setRouting:impact=1[osname.apk]:(com/phonegap/AudioHandler.java:272) uses method: android.media.AudioManager$setRouting:impact=1[osname.apk]:(com/phonegap/AudioPlayer.java:193) uses method: android.media.MediaPlayer$setAudioStreamType:impact=1[osname.apk]:Summary: [5]=1; [4]=0; [3]=0; [2]=3; [1]=4;Summary: [5]=1; [4]=0; [3]=0; [2]=3; [1]=4;Impact Legend: [5]=Severe; [4]=High /context; [3]=Medium /context; [2]=Medium-low /context; [1]=Minor; The offending native code is part of the JVM that we package with the application itself. Therefore, there is nothing we can do to circumvent the issue right now. Further releases of ADF Mobile could replace the current JVM, thus creating more favorable conditions for this to work. I must say I was impressed by the developer tools provided by BlackBerry (formerly Research in Motion), especially the device simulator. Its boot time is an order of magnitude shorter than the Android Emulator's, and it was a joy to use. Does your organization plans to get BlackBerry 10 devices? Is this new platform a more interesting target than Windows Phone? Let us know!   

With the release of their new handsets and operating system, Blackberry occupied lots of media space recently. This prompted me to have a deeper look at their platform and to experiment a bit inrelatio...

ADF

Evaluating EL expressions the Java way in ADF Mobile

Expression language (EL) is used all over the place in JSF and ADF Faces, since it enables the presentation layer (JSPX / JSF pages) to communicate with the application logic (managed beans). ADF Mobile uses exactly the same pattern with its AMX technology, which delivers a JSF-like development experience to build an HTML5-based user interface. The key point here is JSF-like, since internal implementation details may vary between the two. It is sometimes useful to evaluate EL expressions in the managed bean itself rather than delegate the task to the page. Typically, in ADF web applications, this is done like this: import javax.el.ELContext;import javax.el.ExpressionFactory;import javax.el.ValueExpression;import javax.faces.application.Application;import javax.faces.context.FacesContext; public static Object resolveExpression(String expression) {    FacesContext facesContext = getFacesContext();    Application app = facesContext.getApplication();    ExpressionFactory elFactory = app.getExpressionFactory();    ELContext elContext = facesContext.getELContext();    ValueExpression valueExp =         elFactory.createValueExpression(elContext, expression,                                        Object.class);    return valueExp.getValue(elContext);} This code snippet will not work as is in ADF Mobile, since there are no FacesContext or Application objects. Sure, you could retrieve the expression factory by doing this: import oracle.adfmf.framework.api.AdfmfJavaUtilities;import oracle.adfmf.framework.model.AdfELContext;AdfELContext ctx = AdfmfJavaUtilities.getAdfELContext();ExpressionFactory factory = ctx.getExpressionFactory(); But ADF Mobile provides helper methods that will retrieve the context and expression factory behind the scenes for you.  For example, if you want to evaluate in Java an EL expression that retrieves a message (key ERROR_MSG) from a ressource bundle (declared as viewcontrollerBundle): import oracle.adfmf.framework.api.Modelimport oracle.adfmf.framework.contract.adf.NameValuePair;...Model mod = new Model();NameValuePair[] result = null; result = mod.getValue(new String[] { "#{viewcontrollerBundle.ERROR_MSG}" });String value = (String)(result[0].getValue()); The code above will work out of the box if the AMX pages referencing the bean declare the bundle. If that's not the case, you must simply add this line of code before calling getValue on the Model object: mod.loadBundle(<resource_bundle_basename>, <var_attribute>); How would you use this technique in a real-world scenario? Suppose, for example, that you need to bind a single amx:outputText to several different values in a resource bundle, the specific text string to be displayed being determined at runtime. In ADF web applications, you could use nested EL to achieve your goal: #{viewcontrollerBundle[<EL_expression_for_bundle_key>]} This doesn't work in ADF Mobile currently. Thus, you can sidestep the issue by creating a method binding on a bean and reference it in the page. 

Expression language (EL) is used all over the place in JSF and ADF Faces, since it enables the presentation layer (JSPX / JSF pages) to communicate with the application logic (managed beans). ADF...

ADF

Internationalization: which bundle type is right for you?

Choice is one of the fundamental tenets of JDeveloper's approach to development. This probably explains why so many people on the OTN forums and the ADF Enterprise Methodology Group ask for guidance on picking the best alternative to handle specific use cases. Most of the time, the answer will start with: Well... It depends. Developer skills, functional requirements, performance expectations and other variables make it difficult to come up with a single, straightforward recommendation. This is the case with resource bundles.  In the context of the Java platform, a resource bundle is simply a collection of objects related to a specific locale. Each object can be retrieved by its key, which must be unique among all the bundles available to an application. When a program needs a locale-specific resource, such as the string for an error message, it can load it from the resource bundle that is appropriate for the current user's locale. This mechanism allows you to write programs that can: be easily localized, or translated, into different languages handle multiple locales at once be easily modified later to support even more localesSource: Javadoc for the ResourceBundle class.  JDeveloper supports three different types of resource bundles: Java classes, .properties files and XLIFF files. All three behave exactly in the same way at runtime; choosing one type or the other will be completely transparent to the end user and will not likely impact performance or resource usage in a well-designed application. Why would you pick one type over the other, then? .properties files represent the simplest, most straightforward alternative. Here is a sample file. #messages.properties - Jan 20, 2013 PASSWORD_EXPIRED=You password has expired. Please change it.DATABASE=Database updated. The application will now restart.  They are very easy to update even by non-programmers, since their format is so simple. And the ADF  Faces Skin Editor will use them if you override default ADF text resources in your skin. JDeveloper always makes sure to encode such bundles properly at deployment time; that way, international characters are always rendered properly.  You can also use Java classes as resource bundles. In JDeveloper, they are called List Bundles. They are your only option if you want to manage non-string objects or if you need to implement bundle-related business logic. A Java class bundle, for example, could be used to retrieve text strings stored in the database. A typical Java class bundle is reproduced below. public class MyResources extends ListResourceBundle { protected Object[][] getContents() { return new Object[][] { {"PASSWORD_EXPIRED", "You password has expired. Please change it."}, {"DATABASE", "Database updated. The application will now restart."}, }; }} Typically, Java class bundles add complexity to the translation workflow, since classes with updated resources must be recompiled and redeployed. Moreover, non-technical users risk to introduce errors in the code when adding new strings or updating existing ones. It is worth noting that the ADF framework itself stores most of its massages and boilerplate text in Java class resource bundles.  XLIFF (XML Localisation Interchange File Format) is a standard managed by the OASIS consortium. It is supported by specialized tools used by translators, which constitutes its main draw over alternatives. Because of its open nature, XLIFF lends itself a much wider set of use cases than just resource management.  The following XLIFF bundle has been built using JDeveloper 11gR2. <?xml version="1.0" encoding="UTF-8" ?><xliff version="1.1" xmlns="urn:oasis:names:tc:xliff:document:1.1"> <file source-language="en" original="view.ViewControllerBundle" datatype="x-oracle-adf"> <body> <trans-unit id="PASSWORD_EXPIRED"> <source>You password has expired. Please change it.</source> <target/> <note>Message displayed on the logging page when the user password has expired.</note> </trans-unit> <trans-unit id="DATABASE"> <source>Database updated. The application will now restart.</source> <target/> <note>Admin message for use by the batch subsystem. Found in logs.</note> </trans-unit> </body> </file></xliff> As you can see, XLIFF is much more verbose than either Java classes or property files. So, which bundle type is right for you? Well... It depends. ;-) Usually, .properties file will be enough and you will bother with XLIFF's verbosity only if your translators use tools that support it. Java class bundles, on the other hand, are the only way to implement some use cases involving custom business logic but do not necessarily make sense outside specific contexts.

Choice is one of the fundamental tenets of JDeveloper's approach to development. This probably explains why so many people on the OTN forums and the ADF Enterprise Methodology Group ask for guidance...

ADF

The slow JDeveloper startup mystery

I am currently producing my first ADF Insider session. It contains a few recorded demonstrations, which I did using an Oracle Enterprise Linux 6.3 virtual machine. I was pleased by the performance and polish of the OS, and recording was a breeze. If only JDeveloper hadn't been so slow to start... Now, some of you will probably tell me this is business as usual. This is unfair. Since the first 11g release in 2007, JDeveloper's performance has improved steadily. Bex Huff also gave very effective advice on his blog on how to tune your JVM options to improve the tool's speed. And the improvements brought in the 11.1.2 branch show we can expect even more performance for 12c. What I saw in my VM was beyond what I had seen before, anyway. The splash screen was being displayed for nearly a minute before the progress bar showed... And no update centers were available when I checked for updates, preventing me from downloading any. Clearly, something was amiss. With 8gb allocated to it and two virtual CPU cores, resources weren't the problem. After searching on the web for a few minutes and coming back empty-handed, I decided to start JDeveloper on the command line. This is what I got: Out of curiosity, I looked at my /etc/hosts file. For one reason or another, the actual host name (OracleLinux6) wasn't specified for 127.0.0.1 (IPV4) and ::1 (IPV6). Simply adding it to the file did the trick. JDeveloper was itself again afterwards. You see? You shouldn't blame JDeveloper for everything... ;-)

I am currently producing my first ADF Insider session. It contains a few recorded demonstrations, which I did using an Oracle Enterprise Linux 6.3 virtual machine. I was pleased by the performance...

ADF

The great Windows 8 experiment

Two weeks ago, I decided to make the plunge: I upgraded my personal workstation to Windows 8. Why? Sure, I wanted to check if JDeveloper and WebLogic worked correctly. But I must admit my main motivation was curiosity. You see, when I read quotes such as: « On a regular PC, Windows 8 is Mr. Hyde: a monster that terrorizes poor office workers and strangles their productivity. », it was hard to resist the temptation of forging my own opinion.  Today, I am writing this post under Windows 8. And I have no intention to go back to Windows 7. I have very little to report about Oracle's Java tools. They simply just work, as I expected. The JVM  abstracts the underlying OS as on any other platform. I only had two small glitches up to now. 1. Starting the JDeveloper installer for versions 11.1.1.6 and 11.1.2.3 brought a menacing message on the screen, like the one below. It basically says that SmartScreen prevented an unrecognized application from starting. This happens because the JDeveloper installers are not digitally signed. I was able to proceed anyway by following the Informations complémentaires link (More info in English), then clicking on a button labelled Exécuter quand même (Run anyway). JDeveloper then installed as usual, and runs withtout any problems. I must admit the new, simpler UI theme of the Windows 8 desktop suit it well. 2. Using the Application Developer installer to deploy the ADF runtime to a standalone WebLogic 10.3.6 server,  my workstation failed the prerequisites check as shown below: Clicking the Continue button had the expected effect. My standalone WLS instance works without any problems.  I must admit I like the look of the Windows 8 UI; it is cleaner and simpler, without the unneeded transparency that plagued its predecessors. I never liked the Start Menu before, especially in its Vista/7 incarnation. I find myself more productive with the Start Screen. I also find the Windows Key + X keyboard shortcut very useful. Having all those admin-level options available anytime is a great time saver. Obviously, the transition between Windows 8-style apps and Desktop-style ones is abrupt; the UI styles are very dissimilar. And the « charms bar » is difficult to discover and use, since the features it offers vary according to the context. But those are minor annoyances, and I got used to them in a few days. The faster boot times and tighter security easily offset them.  Truth is, no OS currently on the market offers a smooth and coherent user experience.  On Linux, QT-based apps clash with GTK-based ones. On OS X, Apple introduced iOS-like behaviors and applications that are not well-integrated with the rest of the system in the last few versions. The industry is in a transition phase, and it shows. Personally, Windows 8 was criticized the way it was because of one simple thing: resistance to change. This typical quote extracted from a review expresses it well:  « Use Windows 8 for a few minutes and chances are you'll hate it. It takes a lot longer than this to get used to the Modern UI and the way that most things scroll left and right instead of up and down. » Resistance to change is one of the major factors why Windows XP usage is still hovering around 40% in December 2012. It will likely hinder Windows 8 adoption for quite some time.  By the way:  if you want to install and run Oracle VM VirtualBox, be sure you don't have the Windows Hyper-V virtualization feature installed. You will have to use one or the other. Guess which one I kept? :-)

Two weeks ago, I decided to make the plunge: I upgraded my personal workstation to Windows 8. Why? Sure, I wanted to check if JDeveloper and WebLogic worked correctly. But I must admit my...

ADF

Saddling your mountain lion with JDeveloper

Last October, Apple released Java Update 2012-006. This patch brought the Apple-provided JDK for OS X Lion v10.7 and OS X Mountain Lion v10.8 to version 1.6.0_37. At the same time, it disabled the Apple Java plugins and removed the Java Preferences panel that enabled users to manage the various Java releases on their computer. On the Windows and Linux platforms, JDeveloper 11g R1 has been certified  to run on Java 7 since patch set 5. This is not the case on OS X.   ( The above is not a typo. Apple's OS for personal computer is now known as OS X; the « Mac » prefix has been dropped with the 10.8 release. And it's pronounced « Oh-Ess-Ten », by the way. Yes, I am a nitpicker. I know... ) Please note JDeveloper 11g R2 is not certified either. On any platform. It will generally work, but there are known issues with ADF Mobile. Personally, I would recommend to wait for 12c before going to JDK 7.  Now, suppose you have installed Oracle's JDK 7 on your Mac. JDeveloper will not run on it. It will even not install. Susan and I discovered this the hard way while setting up the ADF Mobile hands-on lab we ran at the UKOUG 2012 conference. The lab was a great success nevertheless, attracting nearly a hundred delegates. It was great to see the interest ADF Mobile already generates, especially among PL/SQL Developers and DBAs. But what did we do to make it work?  While Java Update 2012-006 removed the Java Preferences panel, it leaved in place OS X's command-line Java infrastructure. Thus, it is possible to invoke the Apple JDK 6 to start the JDeveloper installer. Suppose your user is named « Fred », and that the JDeveloper installer is on your desktop. You can execute the following command in a terminal window (on a single line) to start the installer:  /usr/libexec/java_home --version 1.6.0  --exec java -jar /Users/Fred/Desktop/jdevstudio11116install.jar  The JDeveloper installer, being provided a valid JDK reference, will set up the IDE and embedded WebLogic Server instance accordingly. Clever engineering at its finest!

Last October, Apple released Java Update 2012-006. This patch brought the Apple-provided JDK for OS X Lion v10.7 and OS X Mountain Lion v10.8 to version 1.6.0_37. At the same time, it disabled the...

ADF

How to force ADF to speak your language (or any common language) in the logs

When I started working for Oracle, one of the first tasks I was given was to contribute some content to a great ADF course Frank and Chris are building. Among other things, they asked me to work on a module about Internationalization. While doing research work, I unearthed a little gem I had overlooked all those years. JDeveloper, as you may know, speaks your language - as long as your language is English, that is. Oracle ADF, on the other hand, is a citizen of the world. It is available in more than 25 different languages. But while this is a wonderful feature for end users, it is rather cumbersome for developers. Why is that? Have you ever tried to search the OTN forums for a solution with a non-English error message as your query? I have, once. But how can you force ADF to use English for its logging operations?  By default, ADF will output its error messages in the selected locale for the operating system account the application server runs on. You can change this behavior is to pass initialization parameters to the JVM used by the application server. It is even possible to specify the language and country/region separately. In the example below, we choose English and the United States respectively. -Duser.language=en -Duser.country=US In the case of WebLogic Server, it is possible to add such parameters in setDomainEnv.sh (or .cmd) to apply the settings to all the managed servers present on a node. In the coming weeks, I will write a few posts about other internationalization issues. Is there anything you would like me to cover? Let me know in the comments.

When I started working for Oracle, one of the first tasks I was given was to contribute some content to a great ADF course Frank and Chris are building. Among other things, they asked me to work on a...

ADF

I owe you an explanation

Welcome to my blog! I am Frédéric Desbiens, a new member of the ADF Product Management team.  I joined Oracle only a few weeks ago. My boss is Grant Ronald, and I have the privilege to work in the same team as Susan Duncan, Frank Nimphius, Lynn Munsinger and Chris Muir. I share with them a passion for all things Java and ADF. With this blog, I hope to help you be more successful with our products – whether you are a customer or a partner. You may have heard of me before. Maybe you have my book in your bookshelf; or maybe we met at a conference. I went to JavaOne, ODTUG Kaleidoscope and Oracle OpenWorld in the past, when I worked for a major consulting firm. I will spare you all the details of my career; you can have a look at my LinkedIn profile if you are curious about my past.  Usually, my posts will be of a technical nature, and will focus on Oracle ADF and Oracle JDeveloper. SOA and portals have always been two topics of interest for me, however, and I will write about them. Over time, you will probably get acquainted with my « strategic » side as well. I devour history books, and always had a tendency to look at the big picture. I will probably not resist to the temptation of mixing IT and history, but this will be occasional, I promise!  At this point, I owe you an explanation about the title of the blog. I am French-Canadian, and wanted to evoke my roots in an obvious yet unobtrusive way. I was born in Chicoutimi, which is one of the main cities found in the Saguenay-Lac-Saint-Jean region. Traditionally, a large part of the wild blueberry production of the province of Québec come from there. A common nickname for the inhabitants is thus Les Bleuets, « The Blueberries » in English. I hope to see you around. You can also follow me on Twitter under  @BlueberryCoder.

Welcome to my blog! I am Frédéric Desbiens, a new member of the ADF Product Management team.  I joined Oracle only a few weeks ago. My boss is Grant Ronald, and I have the privilege to work in the same...