NO_USER_CODE_ERROR while trying to build locally with ant RunMain

I tried to build an apk file from my local .aia file using the ant RunMain task like so,

ant RunMain -Dzip.file=$HOME/MyDownloads/ImageUpload.zip -Duser.name=$USER -Doutput.dir=.

The build fails with no error outputs. Just the Main.java in the buildserver exits with 1.

In order to investigate the issue I changed the buildserver Main.java to show me the error that caused the failure like so,

public static void main(String[] args) {

    CmdLineParser cmdLineParser = new CmdLineParser(commandLineOptions);
    try {
      cmdLineParser.parseArgument(args);
    } catch (CmdLineException e) {
      System.err.println(e.getMessage());
      cmdLineParser.printUsage(System.err);
      System.exit(1);
    }

    ProjectBuilder projectBuilder = new ProjectBuilder(new NullStatReporter());
    ZipFile zip = null;
    try {
      zip = new ZipFile(commandLineOptions.inputZipFile);
    } catch (IOException e) {
      LOG.severe("Problem opening inout zip file: " + commandLineOptions.inputZipFile.getName());
      System.exit(1);
    }
    Result result = projectBuilder.build(commandLineOptions.userName,
                                         zip,
                                         commandLineOptions.outputDir,
                                         commandLineOptions.outputFileName,
                                         commandLineOptions.isForCompanion,
                                         commandLineOptions.isForEmulator,
                                         commandLineOptions.includeDangerousPermissions,
                                         commandLineOptions.extensions,
                                         commandLineOptions.childProcessRamMb,
                                         commandLineOptions.dexCacheDir,
                                         null,
                                         AAB_EXTENSION_VALUE.equals(commandLineOptions.ext));
// the lines I added    
    if (result.getResult() != 0) {
      LOG.severe("Error Compiling 103103:\n Errors:\n" + result.getError() + "Other Outputs: \n" + result.getOutput());
    }
    System.exit(result.getResult());
  }

After doing so, I figured that the error that happens is actually NO_USER_CODE_ERROR defined in Compiler.java in buildserver

Why does this happen? The .aia file I generated was straight from mit app inventor web ui.

You need to make sure that you generate the YAIL before exporting the project. The build server does not do the YAIL generation for you. The option to generate the project YAIL is available under the Build menu if you're logged in as an administrator.

Thanks for the info.
I have 2 followup questions.

  1. For my particular use case, I need to automate the process of building apk from aia. So, is there anyway to login as admin, generate yail from a sequence of command-line commands?

  2. I modified the buildserver code to not treat the NO_USER_CODE as an error and doing so resulted in the gradle build being successful and apk got generated in the target directory. My question is, is there any side effect of apks built using this process( i.e bypassing the NO_USER_CODE_ERROR) ?

Because the error indicates that the AIA doesn't contain the YAIL files, I don't expect the final compiled APK would run successfully. Also, I am not sure about your reference to gradle--App Inventor doesn't use gradle so I'm not sure how this factors in. Code generation is done in the user's browser when they opt to compile their app. We might be able to better advise if we have a sense of why you need to automate compiling so many apps.

1 Like

My reference to gradle was a mistake. I mean't the 'ant build' instead of the 'gradle build', I am so sorry.
I'll explain my use-case.

  1. We are building a NLP based system where, we build apps from text-based description of the app. You can read more about it here: Text2App
  2. Our model predicts and generates the .scm and .bky files under the hood and creates an .aia file. Everything upto this can be done from just one command line command.
  3. But, for this to be called an actual app. We need to generate an ".apk". Currently, users drop the .aia file (generated from our system) into the MIT app inventor web UI and generate the .apk. But, this is not good for user experience. Since, users have to get their app in 2 steps. First build .aia then generate .apk from .aia. Therefore, we are looking for a way to generate .apk from .aia only using command line commands. So, we can automate the entire process.

Is there a way to complete the "YAIL" generation, only using command line commands? Instead of some GUI.

2 Likes

Ok, that helps. We're familiar with your project and it's pretty cool. We're also working on something similar.

You should be able to do this on a server. There are some tests for the code generator in the blocklyeditor module that are used to verify that we don't break the YAIL codegen. The tests are implemented in Javascript and have a Java wrapper that invokes them, but you'd likely just want to write the Javascript to read the scm/bky files and then write out the YAIL file. Once you've got that, you can then compose the AIA for compilation with the buildserver.

Here's an example of how the MoleMash code generation is verified:

1 Like

Thank you so much. This directly points me to what I need to do.

However, this seems quite coupled with the ai codebase. I am not quite sure doing it like the moleMashTest.js would be the optimal way to do it for me, for my simple use case of converting scm&bky to yail.
Would have been great if there was sth like a library/jar/API which takes the .scm and .bky files as input and outputs the corresponding .yail file. Is there something like this?
If not, then is there some documentation regarding what .yail really is(i.e the rules for conversion). This will help me consider if I should write a scm&bky to yail converter from scratch. I made some trial & error using the GUI menu item "Generate Yail" and it helped get an idea of what it is. But, to write a full scm&bky to yail converter from scratch i might need to know the full domain.

1 Like

All of the code gen is done on the client (i.e., in the browser). The code above is simply importing a wrapper HTML that can take the scm/bky file and convert it to yail. You could probably write a node.js wrapper that imports the JavaScript directly and then provides a conversion from scm/bky to yail, but that's more work than just adapting the code above.