X

Shay Shmeltzer's Oracle Development Tools Tips

Developing with Oracle ADF Mobile and ADF Business Components Backend

Shay Shmeltzer
Director of Product Management - Oracle

Update (Nov 2015) - while the approach shown here could still work, we highly recommend that you'll use a REST/JSON architecture instead to access your ADF layer from MAF - as shown in this blog entry.

It's great to finally have the Oracle ADF Mobile solution out there.

If you are not familiar with ADF Mobile - it basically lets you build applications that run on iOS and Android devices using the concepts you already know - components based UI constructions (same idea as JSF), taskflows, data controls, Java and of course JDeveloper.

I created one demo that shows how to build an on-device application that gets data from local Java files (that run on the device - yes we do Java on iOS too) - you can see it here.

However, one thing many of you might be wondering is how can you get data from your database into these mobile applications.

Well if you already built your data access with Oracle ADF Business Components then here is a two step video demo that shows you what to do.

The steps are:

1. Expose ADF Business Components as Services

2. Create an ADF Mobile application that consumes the above services with the Web service data control

Simple right?

That's the whole point of ADF Mobile - making on device application development as simple as possible.

Try it out on your device.

Join the discussion

Comments ( 39 )
  • guest Tuesday, October 23, 2012

    Awesome! I first saw this at the ACE briefing at Open World 2011, and have been waiting very impatiently for it to be released. Glad to see it finally happen!


  • guest Friday, October 26, 2012

    Can you show us how to deploy the app using the Android Emulator. Because, when i tried the app was not loaded to the emulator even through it says 'ADF mobile framework application successfully deployed to Android emulator'


  • Shay Friday, October 26, 2012

    guest - follow this setup tutorial to get the Android Emulator working:

    http://docs.oracle.com/cd/E18941_01/tutorials/MobileTutorial/jdtut_11r2_54_2.html

    Worked for me.


  • guest Wednesday, November 7, 2012

    Shay,

    Thanks for this post. We were trying the same and we were also able successfully deployed into Android emulator.

    But when we try to access the search page, no results are fetched.

    Seems like there is timeout occuring while accessing the WSDL service, which is running in JDev Integrated server.

    We are able to access wsdl test page from emulator browser, when we invoke the same we are getting timeout.

    Appreciate any kind of response from you.

    Thanks.

    Regards,

    Ravi


  • shay Monday, November 12, 2012

    Ravi, I'm not sure what is the issue in your case, but maybe it is some internal networking configuration.

    Maybe you can try this sample to see if generically working with Web services works for you

    https://blogs.oracle.com/mobile/entry/web_services_example_part_1


  • guest Tuesday, November 13, 2012

    Shay,

    Thanks for your response.

    When deployed the application into Android device, it started working but timeout exists in emulator.

    Regards,

    Ravi


  • guest Wednesday, November 14, 2012

    Hi Shay

    Thanks for the post. I have followed all the instructions; however I am not able to deploy to the Android Simulator. My Android simulator starts without any issue. Can u pl. let me know if I am missing something. I am getting the following error

    [06:43:04 PM] Updating Android profile dependencies with FAR profiles created from application projects...

    [06:43:04 PM] ---- Deployment started. ----

    [06:43:04 PM] Target platform is (Android).

    [06:43:05 PM] Beginning deployment of ADF Mobile application "MyMobileApp" to Android using profile "ANDROID_MOBILE_NATIVE_archive1".

    [06:43:05 PM] Checking state of Android Debug Bridge server...

    [06:43:11 PM] Started Android Debug Bridge server.

    [06:43:11 PM] Verifying a single Android emulator is online and connected to the ADB server...

    [06:43:11 PM] Beginning deployment of ADF Mobile application "MyMobileApp" to Android using profile "ANDROID_MOBILE_NATIVE_archive1".

    [06:43:11 PM] Running dependency analysis...

    [06:43:11 PM] Building...

    [06:43:12 PM] Deploying 3 profiles...

    [06:43:13 PM] Wrote Archive Module to D:\SRATH\3_PROJECT\ADF-MOBILE\MyMobileApp\ApplicationController\deploy\ApplicationController.jar

    [06:43:13 PM] WARNING: No Resource Catalog enabled ADF components found to package

    [06:43:13 PM] Wrote Archive Module to D:\SRATH\3_PROJECT\ADF-MOBILE\MyMobileApp\ViewController\deploy\ViewController.jar

    [06:43:13 PM] Starting to prepare the packaging...

    [06:43:13 PM] Verifying Application Controller project exists...

    [06:43:13 PM] Verifying application dependencies...

    [06:43:13 PM] Validating application XML files...

    [06:43:13 PM] Validating XML files in project ApplicationController...

    [06:43:14 PM] Validating XML files in project ViewController...

    [06:43:14 PM] Copying FARs to the ADF Mobile Framework application...

    [06:43:14 PM] Copying FAR from source: ViewController...

    [06:43:14 PM] Copying FAR from source: ApplicationController...

    [06:43:14 PM] Copying Android template...

    [06:43:14 PM] Copying framework resource files...

    [06:43:14 PM] Shutting down Android Debug Bridge server...

    [06:43:14 PM] Deployment cancelled.

    [06:43:14 PM] ---- Deployment incomplete ----.

    [06:43:14 PM] null

    java.lang.NullPointerException

    at oracle.adfmf.common.util.FileUtils.copyDirectory(FileUtils.java:224)

    at oracle.adfmf.framework.dt.deploy.android.core.AndroidDeployer.copyFrameworkResources(AndroidDeployer.java:359)

    at oracle.adfmf.framework.dt.deploy.android.deployers.CopyFrameworkResourcesDeployer.deployImpl(CopyFrameworkResourcesDeployer.java:57)

    at oracle.jdeveloper.deploy.common.AbstractDeployer.deploy(AbstractDeployer.java:145)

    at oracle.adfmf.framework.dt.deploy.common.deployers.AbstractDeployerWrapper.deploy(AbstractDeployerWrapper.java:201)

    at oracle.adfmf.framework.dt.deploy.android.deployers.AndroidDeployerWrapper.deploy(AndroidDeployerWrapper.java:87)

    at oracle.jdeveloper.deploy.common.BatchDeployer.deployImpl(BatchDeployer.java:82)

    at oracle.jdeveloper.deploy.common.AbstractDeployer.deploy(AbstractDeployer.java:145)

    at oracle.jdeveloper.deploy.common.BatchDeployer.deployImpl(BatchDeployer.java:82)

    at oracle.jdeveloper.deploy.common.AbstractDeployer.deploy(AbstractDeployer.java:145)

    at oracle.jdeveloper.deploy.common.BatchDeployer.deployImpl(BatchDeployer.java:82)

    at oracle.jdeveloper.deploy.common.AbstractDeployer.deploy(AbstractDeployer.java:145)

    at oracle.jdevimpl.deploy.fwk.TopLevelDeployer.deployImpl(TopLevelDeployer.java:54)

    at oracle.jdeveloper.deploy.common.AbstractDeployer.deploy(AbstractDeployer.java:145)

    at oracle.jdevimpl.deploy.fwk.DeploymentManager.deployImpl(DeploymentManager.java:481)

    at oracle.jdevimpl.deploy.fwk.DeploymentManager.deploy(DeploymentManager.java:408)

    at oracle.jdeveloper.deploy.DeploymentManager.deploy(DeploymentManager.java:270)

    at oracle.jdeveloper.deploy.cmd.DeployCommand.deploy(DeployCommand.java:375)

    at oracle.jdeveloper.deploy.cmd.DeployCommand$DeploymentProgressShellAdapter$1.deploy(DeployCommand.java:504)

    at oracle.jdevimpl.deploy.fwk.RunnableImpl.run(RunnableImpl.java:372)

    at oracle.jdeveloper.deploy.cmd.DeployCommand.doit(DeployCommand.java:248)

    at oracle.jdevimpl.deploy.DeployCommandRunner$1.run(DeployCommandRunner.java:120)

    at java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:209)

    at java.awt.EventQueue.dispatchEventImpl(EventQueue.java:642)

    at java.awt.EventQueue.access$000(EventQueue.java:85)

    at java.awt.EventQueue$1.run(EventQueue.java:603)

    at java.awt.EventQueue$1.run(EventQueue.java:601)

    at java.security.AccessController.doPrivileged(Native Method)

    at java.security.AccessControlContext$1.doIntersectionPrivilege(AccessControlContext.java:87)

    at java.awt.EventQueue.dispatchEvent(EventQueue.java:612)

    at oracle.javatools.internal.ui.EventQueueWrapper._dispatchEvent(EventQueueWrapper.java:169)

    at oracle.javatools.internal.ui.EventQueueWrapper.dispatchEvent(EventQueueWrapper.java:151)

    at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:269)

    at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:184)

    at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:174)

    at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:169)

    at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:161)

    at java.awt.EventDispatchThread.run(EventDispatchThread.java:122)


  • Shay Wednesday, November 14, 2012

    guest - a better place to post specific errors you get is the JDeveloper forum on OTN.

    From the error at - copyDirectory(FileUtils.java...

    My guess would be that you either have access rights problems or that you are using a directory that has a space in the path for the emulator - something that can cause problems with Java.


  • guest Thursday, November 15, 2012

    Re-installed everything and it started working.

    Thanks

    Shashank


  • Kiran Thursday, November 15, 2012

    Hi Shay,

    First of all, I really appreciate you posting this POC. I am able to deploy the application to emulator and I can see the app on Android emulator. When I try to search for any department, I am getting "cannot connect to localhost on port 7101 : connection refused". My server is started already and the port number is also correct. Did you come across this issue before?


  • Manoj Friday, November 16, 2012

    Hi Shay,

    We really appreciate you posting this POC. I am able to deploy the application to emulator and I can see the app on Android emulator. When I try to search for any department, I am getting "cannot connect to localhost on port 7101 : connection refused".

    My server is started already and the port number is also correct.

    My wsdl is http://localhost:7101/MyApp_2-Model-context-root/AppModuleService?WSDL

    We try to replace localhost with my PC IP address same error is coming.

    Please Help us.


  • Shay Friday, November 16, 2012

    Kiran and Manoj, I'm usually deploying directly to an Android device rather then the emulator (much faster this way). So I haven't played with the emulator's network settings. But this might also have to do with settings in your hosts file. Try and see if the browser in your emulator can access the URL for the WSDL. I would suggest posting these type of questions on the OTN ADF forum.


  • guest Friday, November 16, 2012

    Manoj,

    When we tried this sample, we had same issue of timeout from emulator. We could access the WSDL but not working from the APP.

    When we deployed into actual device, it started working and much faster too.

    Regards,

    Ravi


  • guest Tuesday, November 20, 2012

    Hi Shay,

    Thanx for this excellent post.we tried this and successfully tested in Android Mobile Device.

    And now we are trying to develop login page that authenticating users present in weblogic realm.but we have no idea how to authenticate users present in weblogic realm.

    Could you please help us on this!

    Regards

    Amar


  • Shay Tuesday, November 20, 2012

    guest - for security you can read the Mobile Developer guide where there is a chapter covering this. Andrejus has a sample here: http://andrejusb.blogspot.com/2012/10/adf-mobile-login-functionality.html


  • Ben Friday, December 14, 2012

    Hi Shay,

    Excellent tutorial. When I run the app the details page still shows the first record when I choose different records from the list. How can I force the iterator on the details page to refresh?

    Regards,

    Ben


  • Shay Friday, December 14, 2012

    Ben, correct - you'll need to explicitly invokeAction executable for the setCurrentRowWithKey on the second page.

    There is an example of how to do it here (around 3:40 in the video):

    https://blogs.oracle.com/shay/entry/adf_mobile_update_through_web


  • simo Friday, December 14, 2012

    Hi Shay,

    Thanks for the great post.

    A couple of quick questions...

    I'm guessing that it is, but can we also compile this to weblogic / war?

    Further, are we able to use HTML components in an AMX page? Or is this what the feature / local html functionality is for?

    Cheers,

    Simo


  • shay shmeltzer Friday, December 14, 2012

    Simo, the application I build in the demo is a mobile application that deploys and runs on the device itself. There is no WAR/WebLogic involved in the mobile part.

    You can embed your own HTML in an AMX page with the Verbatim component.


  • simo Saturday, December 15, 2012

    Hi Thanks Shay,

    A couple more if you don't mind... :-). I have separated my model layer out into its own project (resused from another mobile browser project I was working on), but now as I modify my model layer and redeploy the WSDL, what is the best way to 'refresh' the changes in my mobile ADF project? So that my pre-defined Web Service data control is updated with the new objects?

    Further to my earlier question, in general, can Mobile ADF projects be deployed to a WLS server or can you only deploy to device specific. There doesn't seem to be any documentation (that I have found yet) that describes hosting these projects as a web application?

    By the way, I love the interface and in-built transitions. I had initially used jquery mobile over the top of jspx, but this version of ADF provides all that I need now! Well done to the team

    Simo


  • shay shmeltzer Saturday, December 15, 2012

    Simo, to update a web service data control with changes in the WSDL of a remote service - open the DataControls.dcx file, locate the service in the structure pane, and right click on it to choose update.

    ADF Mobile is not a web application - so I'm not sure what part of the app you want to deploy as WAR on WebLogic. The applications are packaged as native device applications and are installed on the device. The backend of Web services can reside on the WLS.


  • guest Monday, December 31, 2012

    Hi Shay,

    I have problem with creating Web service data control.

    When I pase the WSDL URL (first step of wizard), I keep getting an error with a dialog of heading:

    "Invalid WSDL URL" and the dialog says: "oracle/adfinternal/model/adapter/webservice/utils/WSUtils$DefaultAuthPrompter" with an OK button

    What can be a problem ?

    thanks,...


  • Kalyan Monday, December 31, 2012

    Hi Shay,

    I created an mobile appl where I have used Data control web services.

    In Business component I have exposed a simple employee VO returning list of employees without an View Criteria.

    When i use this in the mobile app, I get a blank screen where as I use it with another ADF appl I get the list of employees.

    Is there anything I am missing here.

    Thanks,

    --Kalyan.


  • guest Tuesday, January 8, 2013

    regarding @"Invalid WSDL URL" and the dialog says: "oracle/adfinternal/model/adapter/webservice/utils/WSUtils$DefaultAuthPrompter" with an OK button:

    -In the previous JDev 11.1.2.3 installation, I choose to not install 'UDDI and Xquery support' component of integrated WL server.

    After reinstalling 1.2.3 again with all components, I was able to create DataControl from web service.

    - Thanks,...


  • guest Tuesday, February 5, 2013

    Hi Shay,

    Thanks for the post!

    I have one query that,

    if i need to deploy this application into more than one Android device and how can i deploy this application into customer Android device if he is in another location?

    Regards

    Amar


  • Shay Tuesday, February 5, 2013

    Amar, You can upload your application to the Android Play store and then your customers will be able to download from there.

    Or you can deploy your application to an apk file and then send this to your customer. There are Android apps that will let him install apk files directly.


  • guest Wednesday, March 6, 2013

    I have created the app but the search option works only if the input field is primary key column.It fails if i use the bind variable as my input field as shown in the demo.Am I doing anything wrong?I am pretty new to ADF.


  • guest Thursday, April 25, 2013

    localhost or ipaddress issue can be resolved by using special ipaddress = 10.0.2.2.

    10.0.2.2 - Special alias to your host loopback interface (i.e., 127.0.0.1 on your development machine). localhost would refer emulator itself hence it wont work.


  • guest Friday, October 4, 2013

    Hi,

    I am new in ADF Mobile, and I am developing an app in JDeveloper 11g that should connect to Sql Server DB. I included a driver file in C:\Oracle\Middleware\jdeveloper\jdev\lib\sqljdbc4.jar but I am still getting error when I import java.sql.DriverManager.I even included sqljdbc4.jar file in project properties. Please help me solve this problem.

    Thanks


  • Shay Friday, October 4, 2013

    guest - you can't do direct JDBC connection from ADF Mobile to a server side SQL Server. Instead you need to have server side code exposing the data you need through Web services.

    To get SQLServer JDBC on the server - you'll need to add the driver to the defaultDomain lib directory of the embedded WLS.


  • guest Tuesday, April 8, 2014

    Hi shay sir,

    I am new in adf mobile & want to access web service programmatically can you please show demo of how to invoke web service prgrammatically.


  • Herroug Imade Thursday, August 21, 2014

    hi,

    I created a small application to synchronize contacts with the telehone (samsung galaxy 4. With android system). but when I call the synchronization function, it just added one contact to the list, and it displays the following ecxeption: Error Code 0

    my function in a managed bean that has brought pageFlowScop is:

    public void synchronizeAll(ActionEvent actionEvent)

    {

    ValueExpression vex = AdfmfJavaUtilities.getValueExpression("#{bindings.findEmployesIterator}", Object.class);

    AmxIteratorBinding iter = (AmxIteratorBinding)vex.getValue(AdfmfJavaUtilities.getAdfELContext());

    GenericType row = null;

    iter.getIterator().first();

    String Username = "";

    String Nom = "";

    String Prenom = "";

    String Mobile = null;

    String Mobile1 = null;

    String Mobile2 = null;

    String Mobile3 = null;

    List Mob= new ArrayList();

    String Fix = "";

    String Msg = "";

    String Matri = "";

    String Projet = "";

    String Fonction = "";

    String CodeSoc = "";

    int nb=0;

    int up=0;

    int ins=0;

    Contact newContact=null;

    DeviceManager device= DeviceManagerFactory.getDeviceManager();

    Contact[] contactMob1=null;

    Contact[] contactMob2=null;

    Contact[] contact2=null;

    String ctfount="";

    String n=null,m=null;

    boolean b=true;

    /*---------------------------------------------*/

    ContactField[] phones=null;

    ContactField mobile1= new ContactField();

    ContactField mobile2= new ContactField();

    Contact contactn = new Contact();

    ContactName Name=new ContactName();

    for(int i = 0; i < iter.getIterator().getTotalRowCount(); i++)

    {

    row = (GenericType)iter.getCurrentRow();

    if(row.getAttribute("CodeSoc") != null) CodeSoc = row.getAttribute("CodeSoc").toString();

    if(row.getAttribute("Username") != null) Username = row.getAttribute("Username").toString();

    if(row.getAttribute("Nom") != null) Nom = row.getAttribute("Nom").toString();

    if(row.getAttribute("Prenom") != null) Prenom = row.getAttribute("Prenom").toString();

    if(row.getAttribute("Matri") != null) Matri = row.getAttribute("Matri").toString();

    if(row.getAttribute("Mobile") != null)

    {

    Mobile = row.getAttribute("Mobile").toString();

    if(Mobile.length()==9)

    {

    Mobile1="0"+Mobile;

    Mob.add(Mobile1);

    }

    else if (Mobile.length()==19)

    {

    Mobile1="0"+Mobile.substring(0, 9);

    Mobile2="0"+Mobile.substring(9, 9);

    Mob.add(Mobile);

    Mob.add(Mobile2);

    }

    else if (Mobile.length()==19)

    {

    Mobile1="0"+Mobile.substring(0, 9);

    Mobile2="0"+Mobile.substring(9, 9);

    Mobile3="0"+Mobile.substring(18, 9);

    Mob.add(Mobile1);

    Mob.add(Mobile2);

    Mob.add(Mobile3);

    }

    }

    if(row.getAttribute("Fix") != null) Fix = row.getAttribute("Fix").toString();

    if(row.getAttribute("LibCht") != null) Projet = row.getAttribute("LibCht").toString();

    if(row.getAttribute("Libele") != null) Fonction = row.getAttribute("Libele").toString();

    n=null;m=null; b=true;

    Contact[] contact=device.findContacts("id,name,phoneNumbers",Nom, true);

    for(int u=0;u<contact.length;u++)

    {

    n=contact[u].getName().getFamilyName();

    m=contact[u].getName().getGivenName();

    if(n!=null && n.equalsIgnoreCase(Nom) && m!=null && m.equalsIgnoreCase(Prenom)) {b=false; break;}

    else b=true;

    for(int p=0;p<contact[u].getPhoneNumbers().length;p++)

    ctfount=ctfount+" / "+n+" "+m+" phone="+contact[u].getPhoneNumbers()[p].getValue();

    }

    if(b==true)

    {

    if (Nom !=null && Prenom !=null){

    ins=ins++;

    //newContact=NouveauContact(device,Nom,Prenom,Mobile1,Mobile2,CodeSoc);

    Name.setFamilyName(Nom);

    Name.setGivenName(Prenom);

    contactn.setName(Name);

    //-------------------phone---------------

    if(Mobile1!=null)

    {

    mobile1.setType("mobile");

    mobile1.setValue(Mobile1);

    if(Mobile2!=null)

    {

    mobile1.setType("pro");

    mobile1.setValue(Mobile2);

    phones= new ContactField[]{mobile1,mobile2};

    }

    else phones= new ContactField[]{mobile1};

    contactn.setPhoneNumbers(phones);

    }

    if (contactn !=null)

    {

    newContact=device.createContact(contactn);

    }

    //ctfount=ctfount+" ID="+newContact.getId();

    }

    //-------------------------name--------

    }

    //t1-------------------------------------------------------------------------------------------------

    //nb=nb+1;

    nb=nb+contact.length;

    iter.getIterator().next();

    } //end for annuaire contacte

    throw new AdfException("found:"+nb+":"+ctfount, AdfException.INFO);

    }


  • guest Wednesday, October 15, 2014

    Hi,

    I try create Services exposing ADF BC but I get error to build:

    Error(28,2): annotations are not supported in -source 1.4

    Error(75,16): generics are not supported in -source 1.4

    The lines are:

    (28,2): @SOAPBinding(parameterStyle = SOAPBinding.ParameterStyle.WRAPPED, style = SOAPBinding.Style.DOCUMENT)

    (75,16): List<DepartmentsViewSDO> findDepartmentsView1(@WebParam(mode = WebParam.Mode.IN, name="findCriteria")

    And to run services return error:

    [03:20:12 PM] Deployment cancelled.

    [03:20:12 PM] ---- Deployment incomplete ----.

    [03:20:12 PM] Remote deployment failed (oracle.jdevimpl.deploy.common.Jsr88RemoteDeployer)

    #### Cannot run application DBTest due to error deploying to IntegratedWebLogicServer.

    [Application DBTest stopped and undeployed from Server Instance IntegratedWebLogicServer]

    (I think that this is for errors), and then I can't continue.

    what happens? how can I fix this?

    Thanks!


  • Shay Wednesday, October 15, 2014

    guest - did you create the ADF BC project inside your mobile workspace?

    The ADF BC needs to be a separate application that runs on the server.

    For more please post technical questions on the Oracle MAF Forum on OTN:

    https://community.oracle.com/community/oracle-mobile/oraclemaf


  • guest Friday, October 17, 2014

    Hi guys,

    I viewed and did the same steps but when i test the application in device or simulator this request the next error:

    http status code 500 internal server error: the server encountered an unexpected condition which prevented it from fulfilling the request

    What happen? How can i fix it?

    Thanks!


  • Shay Friday, October 17, 2014

    guest - the 500 error usually means that MAF can't access the Web service - try using the ip-address for the server. Post follow up issues on the MAF forum: https://community.oracle.com/community/java/java_development_tools/application_development_in_java/jdeveloper_and_adf/content


  • Shay Friday, October 17, 2014

    guest, try posting your connection issues on https://community.oracle.com/community/oracle-mobile/oraclemaf


  • Yadira Friday, September 11, 2015

    I´m new using MAF but I Know ADF, so what does means that??

    Can someone help me?

    [12:21:59 PM] The file contains the following errors:

    Error (Line 5, Column 29): Value of attribute url not of NonEmptyString type

    Error (Line 16, Column 7): Element adfmf:localHTML not expected

    Error (Line 17, Column 7): Element adfmf:localHTML not expected

    Error (Line 18, Column 7): Element adfmf:localHTML not expected

    [12:21:59 PM] Shutting down Android Debug Bridge server...

    [12:21:59 PM] Deployment cancelled.

    [12:21:59 PM] ---- Deployment incomplete ----.

    [12:21:59 PM] XML validation failed. (oracle.adfmf.framework.dt.deploy.common.deployers.XMLValidatorDeployer)


  • Shay Friday, September 11, 2015

    Yadira, try asking on the MAF forum on OTN - and I would suggest that you post the specific file that raises these errors.


Please enter your name.Please provide a valid email address.Please enter a comment.CAPTCHA challenge response provided was incorrect. Please try again.