1

I have JDK 1.8 Path set in Visual Studio and I can compile Android 7.0. application without any problems. enter image description here

In order to automatically build signed APK I also have a PS1 script which is supposed to compile the same application using command line MSBUILD. I set JAVA_HOME, JDK_HOME to JDK 1.8. but MSBUILD still uses JDK 1.7. and I get error "Unsupported class version number 52..."

Is there a way how to set JDK location when invoking MSBUILD from command line?

What is even more confusing is that the default Java version on this machine is 1.8 (if I type java -version I get JDK 1.8.0_111.)

UPDATE When executing build with detailed login I can confirm that Xamarin sees JDK 1.8

ResolveSdksTask Outputs:
    AndroidApiLevel: 25
    AndroidApiLevelName: 25
    AndroidNdkPath: D:\Users\milan\Documents\Android\ndk\android-ndk-r10e
    AndroidSdkBuildToolsPath: D:\Utilities\android-sdk\build-tools\25.0.0
    AndroidSdkBuildToolsBinPath: D:\Utilities\android-sdk\build-tools\25.0.0
    AndroidSdkPath: D:\Utilities\android-sdk
    JavaSdkPath: C:\Program Files\Java\jdk1.8.0_111
    MonoAndroidBinPath: C:\Program Files (x86)\MSBuild\Xamarin\Android
    MonoAndroidToolsPath: C:\Program Files (x86)\MSBuild\Xamarin\Android
    MonoAndroidIncludePath: 
    TargetFrameworkVersion: v7.0
    ZipAlignPath: D:\Utilities\android-sdk\build-tools\25.0.0
    SupportedApiLevel: 24
    AndroidSequencePointsMode: None
   Found Android SDK. API levels: 10, 15, 19, 21, 22, 23, 24

But then later on Task "AdjustJavacVersionArguments" changes Javac version to 1.7:

Task "AdjustJavacVersionArguments"
  ToolPath: C:\Program Files\Java\jdk1.8.0_111\\bin
  ToolExe: javac.exe
  EnableProguard: False
  EnableMultiDex: True
  Javac TargetVersion adjusted to: 1.7
  Javac SourceVersion adjusted to: 1.7
Done executing task "AdjustJavacVersionArguments".

Any ideas?

milanio
  • 4,082
  • 24
  • 34
  • Make sure you delete your project's `bin/obj` folder as there is an `sdks.cache` file that holds onto old JDK versions. If you looked at the diagnostic build output of the build, it will tell you where it's getting that JDK reference. – Jon Douglas Nov 23 '16 at 18:07
  • Thanks! I did that couple of times already. :( Maybe another advice what can be wrong? – milanio Nov 23 '16 at 18:34
  • Upload your diagnostic build output log and we will figure out what's going on. `Tools -> Options -> Projects and Solutions -> Build and Run` set logging verbosity to diagnostic. – Jon Douglas Nov 23 '16 at 18:36
  • Thank you @JonDouglas. I've updated the question with relevant part of the logfile. – milanio Nov 23 '16 at 20:20
  • Please upload the full log. I am looking for other aspects. – Jon Douglas Nov 23 '16 at 20:24

1 Answers1

1

This looks like a combination of issues.

1) Multidex fails to create the main list due to API 24(Android 7.0) does not support JDK 1.7.

CREATEMULTIDEXMAINDEXCLASSLIST : error : Can't read [C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\MonoAndroid\v7.0\mono.android.jar] (Can't process class [android/app/ActivityTracker.class] (Unsupported class version number [52.0] (maximum 51.0, Java 1.7))) [D:\src\anqueto\trunk\que\mikonboard.que.androidClient\mikonboard.que.androidClient.csproj]

Also related: Xamarin.Android Proguard - Unsupported class version number 52.0

2) javac is adjusting to JDK 1.7 (Thus you still have it installed).

Here is the Task decompiled:

  public class AdjustJavacVersionArguments : ToolTask
  {
    [Required]
    public new string ToolPath { get; set; }

    public bool EnableProguard { get; set; }

    public bool EnableMultiDex { get; set; }

    [Output]
    public string TargetVersion { get; set; }

    [Output]
    public string SourceVersion { get; set; }

    protected override string ToolName
    {
      get
      {
        return !OS.IsWindows ? "javac" : "javac.exe";
      }
    }

    public override bool Execute()
    {
      this.Log.LogDebugMessage("ToolPath: {0}", (object) this.ToolPath);
      this.Log.LogDebugMessage("ToolExe: {0}", (object) this.ToolExe);
      this.Log.LogDebugMessage("EnableProguard: {0}", (object) this.EnableProguard);
      this.Log.LogDebugMessage("EnableMultiDex: {0}", (object) this.EnableMultiDex);
      if (!this.EnableProguard && !this.EnableMultiDex)
        return true;
      Process process = Process.Start(new ProcessStartInfo(Path.Combine(this.ToolPath, this.ToolExe ?? this.ToolName), "-version")
      {
        RedirectStandardOutput = true,
        RedirectStandardError = true,
        UseShellExecute = false,
        CreateNoWindow = true,
        WindowStyle = ProcessWindowStyle.Hidden
      });
      process.WaitForExit();
      string str1 = process.StandardError.ReadLine();
      if (!str1.StartsWith("javac ") || !str1.Substring(6).StartsWith("1.8"))
        return true;
      string str2 = "1.7";
      this.SourceVersion = str2;
      this.TargetVersion = str2;
      this.Log.LogDebugMessage("Javac TargetVersion adjusted to: {0}", (object) this.TargetVersion);
      this.Log.LogDebugMessage("Javac SourceVersion adjusted to: {0}", (object) this.SourceVersion);
      return true;
    }

    protected override string GenerateFullPathToTool()
    {
      return Path.Combine(this.ToolPath, this.ToolExe);
    }
  }

It specifically looks like it fails to return true; on these lines:

string str1 = process.StandardError.ReadLine();
if (!str1.StartsWith("javac ") || !str1.Substring(6).StartsWith("1.8"))
        return true;

And thus it adjusts to 1.7:

string str2 = "1.7";
this.SourceVersion = str2;
this.TargetVersion = str2;
this.Log.LogDebugMessage("Javac TargetVersion adjusted to: {0}", (object) this.TargetVersion);
this.Log.LogDebugMessage("Javac SourceVersion adjusted to: {0}", (object) this.SourceVersion);
return true;

I would say it might be easiest to uninstall JDK 1.7 and only have JDK 1.8 installed to see if that resolves your issue.

Otherwise try to ensure the project and your JDK are on the same drive. You seem to have bits and pieces on both your C:\ and D:\ drives. I would keep all of your development tools on one drive.

Community
  • 1
  • 1
Jon Douglas
  • 13,006
  • 4
  • 38
  • 51
  • Thanks a lot! Unfortunately, uninstalling JDK 1.7 (and restarting system) does not resolve the issue. It seems that only valid solution for now is rollback to Java 1.7 & Android 6.0. because no matter what AdjustJavacVersionArguments task will be executed if MultiDex = true – milanio Nov 23 '16 at 22:21
  • Did you try the suggestion from the bottom of my post RE: Moving things all to one drive? Perhaps it cannot even find Java on one of those drives and thus defaults to 1.7 which picks up later. – Jon Douglas Nov 23 '16 at 22:23
  • I tried that as well (everything on C: drive) - the same result. I believe the problem is that it actually uses JDK 1.8 but it sets -source parameter to 1.7 (see http://docs.oracle.com/javase/8/docs/technotes/tools/windows/javac.html). Because of that javac refuses to compile. Maybe I'm doing something completely wrong and scenario MultiDex + Android 7.0. is not yet supported. Is that possible? – milanio Nov 23 '16 at 22:55
  • Now that I think about it, it's probably because CREATEMULTIDEXMAINDEXCLASSLIST invokes Proguard home via `PROGUARD_HOME=C:\Android\android-sdk\tools\proguard\` thus my answer here would solve the problem: http://stackoverflow.com/questions/39514518/xamarin-android-proguard-unsupported-class-version-number-52-0 – Jon Douglas Nov 23 '16 at 23:43
  • Hi @Jon Douglas, due to another problem I was finally forced to upgrade to compile with SDK Api25 (Android 7.1) so I had to come back to this problem. And the solution is indeed your advice to upgrade Proguard. Can you please just update the answer and I will accept it? Thanks for your help! – milanio Apr 24 '17 at 12:40
  • Added a link to the question that's related. No problem! – Jon Douglas Apr 24 '17 at 15:27