0

We have a stateless Java Application which I want to be deployed in Azure fabric. I have installed the Fabric SDK and Visual studio tools as per the documentation.

After that I have created the Service Fabric application "Guest Executable" template and my project structure is like below:

enter image description here

I have followed steps similar to the documentation as in https://azure.microsoft.com/en-us/documentation/articles/service-fabric-deploy-existing-app/

My ServiceManifest.xml is below:

<?xml version="1.0" encoding="utf-8"?>
<ServiceManifest Name="Guest1Pkg"
                 Version="1.0.0"
                 xmlns="http://schemas.microsoft.com/2011/01/fabric"
                 xmlns:xsd="http://www.w3.org/2001/XMLSchema"
                 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  <ServiceTypes>
    <StatelessServiceType ServiceTypeName="Guest1Type" UseImplicitHost="true" />
  </ServiceTypes>
  <CodePackage Name="Code" Version="1.0.0">
    <EntryPoint>
      <ExeHost>
        <Program>HelloWorld.war</Program>
        <Arguments></Arguments>
        <WorkingFolder>CodePackage</WorkingFolder>
      </ExeHost>
    </EntryPoint>
  </CodePackage>
  <ConfigPackage Name="Config" Version="1.0.0" />
  <Resources>
    <Endpoints>
      <Endpoint Name="JavaAppTypeEndpoint" Protocol="http" Port="8080" Type="Input" />
    </Endpoints>
  </Resources>
</ServiceManifest>

My ApplicationManifest.xml snippet is below:

<?xml version="1.0" encoding="utf-8"?>
<ApplicationManifest ApplicationTypeName="Application1Type"
                     ApplicationTypeVersion="1.0.0"
                     xmlns="http://schemas.microsoft.com/2011/01/fabric"
                     xmlns:xsd="http://www.w3.org/2001/XMLSchema"
                     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  <Parameters>
    <Parameter Name="Guest1_InstanceCount" DefaultValue="-1" />
  </Parameters>
  <ServiceManifestImport>
    <ServiceManifestRef ServiceManifestName="Guest1Pkg" ServiceManifestVersion="1.0.0" />
    <ConfigOverrides />
  </ServiceManifestImport>
  <DefaultServices>
    <Service Name="Guest1">
      <StatelessService ServiceTypeName="Guest1Type" InstanceCount="[Guest1_InstanceCount]">
        <SingletonPartition />
      </StatelessService>
    </Service>
  </DefaultServices>
</ApplicationManifest>

I deployed to Service Fabric Explorer in my local, and the build and publish steps are good without any errors:

-------- Package: Project: Application1 succeeded, Time elapsed: 00:00:00.3530634 --------
2>Started executing script 'Deploy-FabricApplication.ps1'.
2>. 'C:\Users\samanoha\Documents\Visual Studio 2015\Projects\Application1\Application1\Scripts\Deploy-FabricApplication.ps1' -ApplicationPackagePath 'C:\Users\samanoha\Documents\Visual Studio 2015\Projects\Application1\Application1\pkg\Debug' -PublishProfileFile 'C:\Users\samanoha\Documents\Visual Studio 2015\Projects\Application1\Application1\PublishProfiles\Local.5Node.xml' -DeployOnly:$true -UnregisterUnusedApplicationVersionsAfterUpgrade $false -OverrideUpgradeBehavior 'None' -OverwriteBehavior 'Always' -SkipPackageValidation:$true -ErrorAction Stop
2>Copying application to image store...
2>Copy application package succeeded
2>Registering application type...
2>Register application type succeeded
2>Removing application package from image store...
2>Remove application package succeeded
2>Finished executing script 'Deploy-FabricApplication.ps1'.
2>Time elapsed: 00:00:01.9327912
========== Build: 1 succeeded or up-to-date, 0 failed, 0 skipped ==========
========== Deploy: 1 succeeded, 0 failed, 0 skipped ==========

Started executing script 'Publish-NewServiceFabricApplication'.
[void](Connect-ServiceFabricCluster); Import-Module 'C:\Program Files\Microsoft SDKs\Service Fabric\Tools\PSModule\ServiceFabricSDK\ServiceFabricSDK.psm1'; Publish-NewServiceFabricApplication -ApplicationPackagePath 'C:\Users\samanoha\Documents\Visual Studio 2015\Projects\Application1\Application1\pkg\Debug' -ApplicationParameterFilePath 'C:\Users\samanoha\Documents\Visual Studio 2015\Projects\Application1\Application1\PublishProfiles\..\ApplicationParameters\Local.5Node.xml' -ApplicationParameter @{_WFDebugParams_='[]'} -Action Create -SkipPackageValidation:$true -ErrorAction Stop
Creating application...


ApplicationName        : fabric:/Application1
ApplicationTypeName    : Application1Type
ApplicationTypeVersion : 1.0.0
ApplicationParameters  : { "_WFDebugParams_" = "[]" }

Create application succeeded.


Finished executing script 'Publish-NewServiceFabricApplication'.
Time elapsed: 00:00:01.8691591
Started executing script 'Get-ServiceFabricApplicationStatus'.
[void](Connect-ServiceFabricCluster); Import-Module 'C:\Program Files\Microsoft SDKs\Service Fabric\Tools\PSModule\ServiceFabricSDK\ServiceFabricSDK.psm1'; Get-ServiceFabricApplicationStatus -ApplicationName 'fabric:/Application1' -ErrorAction Stop
The application has started.
Service Status:
fabric:/Application1/Guest1 is ready.

The application is ready.
Finished executing script 'Get-ServiceFabricApplicationStatus'.
Time elapsed: 00:00:01.0230548

But the application health state shows error and the event is

"Error event: SourceId='System.Hosting', Property='CodePackageActivation:Code:EntryPoint'.
There was an error during CodePackage activation."

enter image description here

I don't have any idea what might be the issue here in deployment, whether anything needs to be included in Application service Entry point in addition to mentioned above.

Also, The Java webapplication when deployed on Standalone tomcat has the following context http://localhost:8080/HelloWorld/hello . If the Application is deployed in Service fabric cluster, will the URL context for this remains same or should it be something like http://localhost:8080/Application1/Guest1/HelloWorld/hello due to the Azure fabric wrapper around it?

Satheesh
  • 803
  • 1
  • 11
  • 28

4 Answers4

1

Finally it turned out that we need to separately install Java in the Host virtual machine (Azure VM or local Desktop) and then we have to reference the java path.

So my service manifest is

<EntryPoint>
      <ExeHost>
        <Program>scripts\launchConfig.cmd</Program>
        <Arguments></Arguments>
        <WorkingFolder>CodePackage</WorkingFolder>
        <ConsoleRedirection FileRetentionCount="5" FileMaxSizeInKb="2048"/>
      </ExeHost>
</EntryPoint>

I have created a folder called scripts under Code folder and the script file "launchConfig.cmd" has just single line as below:

"C:\Program Files (x86)\Java\jre1.8.0_101\bin\java.exe" -jar HelloWorld.war

We might need to remove the path hardcodings, but this is how it referred finally.

Satheesh
  • 803
  • 1
  • 11
  • 28
  • If this is just running java on that war, isn't that going to start listening on whatever port the java app is setup to listen on? I tried this method on a spring webapi war application on a one machine dev asf cluster and it succeeded on one "node" and failed on the other two, which would make sense if the other two "nodes" were trying to open port 8080 which node 1 already opened. – Greg Nov 01 '16 at 19:34
  • Yes @GregoryBillings, you are right related to java execution on specified ports. But initially I was in an impression that platform dependency ie. Java installation itself will be taken care by ServiceFabric, but it turned out that it was an additional step we need to make sure it is installed. – Satheesh Nov 07 '16 at 19:29
  • Ah, gotcha @Satheesh. This is still highly disconcerting. I would expect the framework to handle port redirection for you, so you didn't have to manually keep up with the ports. My bet would be they're going to rely heavily on docker for this functionality. – Greg Nov 08 '16 at 15:29
1

As described in an earlier answer, one approach is to separately install Java onto the machines.

I wrote about an alternative approach at https://blog.vjrantal.net/2017/04/11/high-availability-java-hosting-in-azure-using-service-fabric/ which is based on packaging the wanted Java runtime into the app package.

0

The thing you put in the Program config needs to be something that is executable (.exe, .cmd, etc). Service Fabric will try to execute whatever you put in there.

For example, in the doc you linked to, to execute a node.js app the Program is node.exe and the Arguments point to the application:

<ExeHost>
  <Program>node.exe</Program>
  <Arguments>bin/www</Arguments>
  <WorkingFolder>CodePackage</WorkingFolder>
</ExeHost>
Vaclav Turecek
  • 9,020
  • 24
  • 29
  • Thanks! Can you guide me how to run J2EE war packages with Fabric? Is there any additional configs which needs to configured for JVM setup, since we dont have .exe type executables here. Any reference documentation would be great – Satheesh Sep 21 '16 at 20:05
  • If you can run it from command line (does it have an embedded server?) like this: java -jar HelloWorld.war, then the Program is java and the arguments are -jar HelloWorld.war. Does that work? – Vaclav Turecek Sep 21 '16 at 23:32
  • Thanks! I built war file with embedded tomcat container, which works well in my local when launched like "java -jar HelloWorld.war". When I tried to pass the same as you mentioned, I got error "Register-ServiceFabricApplicationType : The EntryPoint java is not found." Do we need any additional setup for Java inatallation in Azure service fabric? specifying as java.exe also doesn't work – Satheesh Sep 22 '16 at 16:54
  • is it possible to follow the steps to deploy java based application on Windows OS locally? – Dhrumil Shah Nov 15 '18 at 13:25
0

The entry point should be a command. HelloWorld.war is not a command. Guest executable is designed for running a command or exe.

<SetupEntryPoint>
     <ExeHost>
         <Program>scripts\launchConfig.cmd</Program>
     </ExeHost>
  </SetupEntryPoint>

and launchConfig.cmd should contain script for running Tomcat or jboss (or any j2ee app server). You should install java, configure tomcat/ jboss , deploy HelloWorld.war in and configure the port before running the server.

Raghu K Nair
  • 3,854
  • 1
  • 28
  • 45