Bug 13334 - Ocassional Build Failures with "javacerror : <identifier> expected"
Summary: Ocassional Build Failures with "javacerror : <identifier> expected"
Alias: None
Product: Android
Classification: Xamarin
Component: General ()
Version: 4.6.x
Hardware: Macintosh Mac OS
: --- normal
Target Milestone: ---
Assignee: Jonathan Pryor
Depends on:
Reported: 2013-07-19 02:40 UTC by Johannes Rudolph
Modified: 2013-07-19 05:51 UTC (History)
2 users (show)

Is this bug a regression?: ---
Last known good build:

Notice (2018-05-24): bugzilla.xamarin.com is now in read-only mode.

Please join us on Visual Studio Developer Community and in the Xamarin and Mono organizations on GitHub to continue tracking issues. Bugzilla will remain available for reference in read-only mode. We will continue to work on open Bugzilla bugs, copy them to the new locations as needed for follow-up, and add the new items under Related Links.

Our sincere thanks to everyone who has contributed on this bug tracker over the years. Thanks also for your understanding as we make these adjustments and improvements for the future.

Please create a new report on Developer Community or GitHub with your current version information, steps to reproduce, and relevant error messages or log files if you are hitting an issue that looks similar to this resolved bug and you do not yet see a matching new report.

Related Links:

Description Johannes Rudolph 2013-07-19 02:40:36 UTC
I'm occasionally getting the following build error:

  Library/Frameworks/Mono.framework/External/xbuild/Xamarin/Android/Xamarin.Android.Common.targets (_CompileJava target) ->

  obj/Release/android/src/rowinginmotion/mobile/boatapp/droid/guide/2GFlHRvGYu.java(4,13): javacerror : expected

The java file in question seems to be a an auto-generated wrapper for a WebViewClient and looks like this:

  package rowinginmotion.mobile.boatapp.droid.guide;

  public class 2GFlHRvGYu extends android.webkit.WebViewClient implements mono.android.IGCUserPeer {

I assume the errors appear because Xamarin is generating invalid class names. According to the java spec, class names may not start with a number: http://docs.oracle.com/javase/specs/jls/se7/html/jls-3.html#jls-3.8

I'm using the latest version 4.0.9 (build 12) stable at the time of writing.
Comment 1 Atsushi Eno 2013-07-19 04:01:29 UTC
The description misses how you get such a file (neither repro project nor how to create such a project) so we cannot say anything for sure right now.

Our Android Callable Wrapper is generated from C# types. And any C# type name that begins with number doesn't compile to dll and thus it won't proceed to java compilation step.

We expect any weird input java files filtered out *by user* unless it is likely from proguard. For anything else we can't judge as user might expect anything bundled (and any incorrect expectation be corrected) or silently filtered.
Comment 2 Johannes Rudolph 2013-07-19 05:05:39 UTC
The bug occurs non-deterministically - so it's hard to come up with a Repro.

I'm not using ProGuard and haven't specified any additional java files for input manually (so I assume this java file is auto-generated).

In my project, I have a C# class that inherits WebViewClient for which I assume this wrapper is auto-generated by Mono.Droid. I may be using the wrong terminology here, so it may not be a "wrapper". I can't say exactly what this weird java class is or why it's beeing generated. All I know is that it is being generated automatically, because the next time I do a clean re-build the same java class may be generated with a proper, random name and the build succeeds. I will post the full Java class in my next comment.

Here's the java class this may be for:

using Android.Webkit;
using System;
using Android.Content;

namespace RowingInMotion.Mobile.BoatApp.Droid.Guide
	class GuideWebViewClient : WebViewClient
		readonly IGuideViewDelegate _delegate;

		public GuideWebViewClient ( IGuideViewDelegate del)
			_delegate = del;

		public override void OnPageFinished( WebView view, string url )
			base.OnPageFinished( view, url );

			bool guideDidFinish = true;

			if (guideDidFinish)

		 * This will ensure, that the user does not open his real browser, if he clicks 
		 * on a link.
		public override bool ShouldOverrideUrlLoading( WebView view, string url )
			bool isExternalPageRequested = url.StartsWith( "http" );

			if (isExternalPageRequested)
				//Pass it to the system, doesn't match your domain
				Intent intent = new Intent(Intent.ActionView);
				intent.SetData( Android.Net.Uri.Parse(url) );
				view.LoadUrl( url );

			return true;
Comment 3 Johannes Rudolph 2013-07-19 05:06:31 UTC
Here's the java class. Maybe you can recognize what it is:

package rowinginmotion.mobile.boatapp.droid.guide;

public class 2GFlHRvGYu
	extends android.webkit.WebViewClient
	static final String __md_methods;
	static {
		__md_methods = 
			"n_onPageFinished:(Landroid/webkit/WebView;Ljava/lang/String;)V:GetOnPageFinished_Landroid_webkit_WebView_Ljava_lang_String_Handler\n" +
			"n_shouldOverrideUrlLoading:(Landroid/webkit/WebView;Ljava/lang/String;)Z:GetShouldOverrideUrlLoading_Landroid_webkit_WebView_Ljava_lang_String_Handler\n" +
		mono.android.Runtime.register ("RowingInMotion.Mobile.BoatApp.Droid.Guide.2GFlHRvGYu, RowingInMotion.Mobile.BoatApp.Droid, Version=, Culture=neutral, PublicKeyToken=null", 2GFlHRvGYu.class, __md_methods);

	public 2GFlHRvGYu ()
		super ();
		if (getClass () == 2GFlHRvGYu.class)
			mono.android.TypeManager.Activate ("RowingInMotion.Mobile.BoatApp.Droid.Guide.2GFlHRvGYu, RowingInMotion.Mobile.BoatApp.Droid, Version=, Culture=neutral, PublicKeyToken=null", "", this, new java.lang.Object[] {  });

	public void onPageFinished (android.webkit.WebView p0, java.lang.String p1)
		n_onPageFinished (p0, p1);

	private native void n_onPageFinished (android.webkit.WebView p0, java.lang.String p1);

	public boolean shouldOverrideUrlLoading (android.webkit.WebView p0, java.lang.String p1)
		return n_shouldOverrideUrlLoading (p0, p1);

	private native boolean n_shouldOverrideUrlLoading (android.webkit.WebView p0, java.lang.String p1);

	java.util.ArrayList refList;
	public void monodroidAddReference (java.lang.Object obj)
		if (refList == null)
			refList = new java.util.ArrayList ();
		refList.add (obj);

	public void monodroidClearReferences ()
		if (refList != null)
			refList.clear ();
Comment 4 Atsushi Eno 2013-07-19 05:45:40 UTC
>         mono.android.Runtime.register
RowingInMotion.Mobile.BoatApp.Droid, Version=, Culture=neutral,
PublicKeyToken=null", 2GFlHRvGYu.class, __md_methods);

This registers managed class to our runtime. As of this code being generated, the managed dll already has the name 2GFlHRvGYu. It is something you (or any intervening post code processors) generated.
Comment 5 Johannes Rudolph 2013-07-19 05:51:01 UTC
You're correct, theres a .NET obfuscator in between (sorry for not taking this into account when you mentioned Proguard, I discarded that too fast because it's a java obfuscator...)

Can be closed. Thanks for your help diagnosing this!