Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Xamarin and APK Signing - Change path to JarSigner

When I build my Xamarin project the version of the jarsigner tool it uses is ALWAYS from \Java\jdk1.6.0_39\bin\

I was wondering if we could change to different version of JDK.

Looking at the build output it seems to boil down to whatecer MSBuild../Xamerin/Android.Build.Tasks.dll tells it.... (see below)

Is there a way to get the build to point to another path...a later version of the JDK?whatever

11>Using "AndroidSignPackage" task from assembly "C:\Program Files (x86)\MSBuild\Xamarin\Android\Xamarin.Android.Build.Tasks.dll".
11>Task "AndroidSignPackage"
11>  C:\Program Files (x86)\Java\jdk1.6.0_39\\bin\jarsigner.exe
like image 279
AJM Avatar asked Mar 16 '23 10:03

AJM


1 Answers

Looking at the Xamarin's Custom MSBuild Task Library (C:\Program Files (x86)\MSBuild\Xamarin\Android\Xamarin.Android.Build.Tasks.dll) AndroidSignPackage extends AndroidToolTask which extends the built in ToolTask class. It also looks like they properly implemented it as well so you should be able to simply pass the additional optional parameter ToolPath.

If you're calling the task directly from MSBuild as part of a custom build process the command might looks like this:

<AndroidSignPackage
  UnsignedApk="pathtounsignedapk"
  SignedApkDirectory="signedapkoutputdir"
  Keystore="yourkeystorelocation"
  KeyAlias="thekeyaliasusedtosign"
  StorePass="thepasswordforthekeystore"
  ToolPath="NEWPATHTOJAVASDK" />

If you're trying to do this integrated within the Visual Studio Environment you'll need to start groveling around in their *.Targets file and chase it down, if you're not comfortable with MSBuild I do not recommend doing so.

BEYOND THIS POINT NO WARRANTY GROVELING IN UNDOCUMENTED LAND COULD AND WILL BREAK AT THE LEAST OPPORTUNE TIME AS PER MURPHY

In my version of the Xamarin Toolchain in Xamarin.Android.Common.targets (C:\Program Files (x86)\MSBuild\Xamarin\Android\Xamarin.Android.Common.targets) we see that the AndroidSignPackage is called from within the _Sign target, it appears that, at least in this version, are passing the ToolPath attribute, which in this version is defined as $(JarsignerToolPath), looking further up in the .targets file we see that this is defined as follows:

<CreateProperty Value="$(_JavaSdkDirectory)\bin">
    <Output TaskParameter="Value" PropertyName="JarsignerToolPath"
            Condition="'$(JarsignerToolPath)' == ''"
    />
</CreateProperty>

It looks like they were really nice (at least in this version) at validate that $(JarsignerToolPath) is not defined prior to setting this value, if it is this task will not do anything and take the existing value.

At this point in time you have a couple of options, what it boils down to is they'll respect the MSBuild Property $(JarsignerToolPath) however it comes in before this build process. If you read the documentation on MSBuild you'll see that you can define that property in a couple of ways.

The most popular (and my recommendation) is to declare it straight up in your MSBuild Script (remember that CSPROJ files are just MSBuild Scripts) in one of the property groups (I'd recommend under a build configuration) you can simply define this property explicitly for example:

<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|JDK17' ">
  <DebugType>pdbonly</DebugType>
  <Optimize>true</Optimize>
  <OutputPath>bin\Release\</OutputPath>
  ... (Additional properties trimmed) ...
  <JarsignerToolPath>C:\Program Files (x86)\Java\jdk1.7.0_71\bin</JarsignerToolPath>
</PropertyGroup>

Alternatively you can set an Environment variable prior to launching Visual Studio/MSBuild process performing the build that sets the JarsignerToolPath to the correct property.

Obviously you can use the above knowledge to take it even further and look to research if you could replace $(_JavaSdkDirectory)...

like image 135
aolszowka Avatar answered Mar 23 '23 05:03

aolszowka