I’m working on a cross-platform app that uses sysex to configure MIDI devices. Since we last pushed an update, Jan 2nd (using JUCE 5.4.1) it seems that something’s changed in the JUCE backend and sysex messages over around 20 bytes are being truncated - breaking our communication protocol completely.
I stripped back the functionality of our app so it just connects to available midi ports and prints sent/received midi data as raw hex bytes. I’m unable to receive longer sysex messages without truncation, but I can send the same exact message out just fine. Other messages (Note, CC, Program Change) seem to be unaffected when this is happening.
I’ve tried rolling our app code back to the last stable release with identical results, but installing the same release version from the play store still works perfectly on all devices i’ve tested - which is what makes me think it must be a change in JUCE.
I’ve tested on multiple devices (API 24 and API 27), building using Juce 5.4.3, AS 3.3.2, Gradle 4.10.1 on Mac.
Have there been any changes recently that could explain this behaviour, or do you have any ideas on how I can debug this further?
To help narrow this down, you said the last working release you did was in January - was this using the tagged 5.4.1 release and not the develop branch? And the tests that you are doing now are with the tagged 5.4.3 release?
Can you try reverting this commit and see if it fixes your issue?
I’ve spent the afternoon trying to test this but have been running into some roadblocks: reversing that linked commit gives me build errors in the projucer:
In file included from /Users/lukesaxton/Documents/dev/JUCE/extras/Projucer/Source/ProjectSaving/jucer_ProjectExporter.cpp:34:
/Users/lukesaxton/Documents/dev/JUCE/extras/Projucer/Source/ProjectSaving/jucer_ProjectExport_Android.h:1496:89: error: no viable conversion from 'RelativePath' to 'const juce::File'
if ((! projectItem.shouldBeCompiled()) || (! shouldFileBeCompiledByDefault (file))
^~~~
In file included from /Users/lukesaxton/Documents/dev/JUCE/extras/Projucer/Source/ProjectSaving/jucer_ProjectExporter.cpp:27:
In file included from /Users/lukesaxton/Documents/dev/JUCE/extras/Projucer/Source/ProjectSaving/../Application/jucer_Headers.h:29:
In file included from ../../JuceLibraryCode/../JuceLibraryCode/JuceHeader.h:17:
In file included from ../../../../modules/juce_analytics/juce_analytics.h:55:
In file included from ../../../../modules/juce_gui_basics/juce_gui_basics.h:57:
In file included from ../../../../modules/juce_graphics/juce_graphics.h:57:
In file included from ../../../../modules/juce_core/juce_core.h:294:
../../../../modules/juce_core/files/juce_File.h:63:5: note: candidate constructor not viable: no known conversion from 'RelativePath' to 'const juce::String &' for 1st argument
File (const String& absolutePath);
^
../../../../modules/juce_core/files/juce_File.h:66:5: note: candidate constructor not viable: no known conversion from 'RelativePath' to 'const juce::File &' for 1st argument
File (const File&);
^
../../../../modules/juce_core/files/juce_File.h:87:5: note: candidate constructor not viable: no known conversion from 'RelativePath' to 'juce::File &&' for 1st argument
File (File&&) noexcept;
^
In file included from /Users/lukesaxton/Documents/dev/JUCE/extras/Projucer/Source/ProjectSaving/jucer_ProjectExporter.cpp:28:
/Users/lukesaxton/Documents/dev/JUCE/extras/Projucer/Source/ProjectSaving/jucer_ProjectExporter.h:81:61: note: passing argument to parameter 'path' here
virtual bool shouldFileBeCompiledByDefault (const File& path) const;
^
1 error generated.
I also tried seeing if I can roll the whole branch back to v5.4.1. tagged commit but am just getting an extremely opaque gradle error:
My process was rebuilding the projucer, deleting all files in android directory and re-saving the project. I’ve also tried creating a new android studio project - same problem.
I also tried resetting the whole juce branch back to 5.4.1 and rebuilding the projucer etc. - same results.
Rolling android studio back to 3.2.1 with juce 5.4.1 yeilded a slightly different error message:
org.gradle.api.ProjectConfigurationException: A problem occurred configuring project ':app'.
at org.gradle.configuration.project.LifecycleProjectEvaluator.wrapException(LifecycleProjectEvaluator.java:79)
at org.gradle.configuration.project.LifecycleProjectEvaluator.addConfigurationFailure(LifecycleProjectEvaluator.java:73)
at org.gradle.configuration.project.LifecycleProjectEvaluator.access$400(LifecycleProjectEvaluator.java:54)
at org.gradle.configuration.project.LifecycleProjectEvaluator$NotifyAfterEvaluate.run(LifecycleProjectEvaluator.java:200)
at org.gradle.internal.operations.DefaultBuildOperationExecutor$RunnableBuildOperationWorker.execute(DefaultBuildOperationExecutor.java:300)
at org.gradle.internal.operations.DefaultBuildOperationExecutor$RunnableBuildOperationWorker.execute(DefaultBuildOperationExecutor.java:292)
at org.gradle.internal.operations.DefaultBuildOperationExecutor.execute(DefaultBuildOperationExecutor.java:174)
at org.gradle.internal.operations.DefaultBuildOperationExecutor.run(DefaultBuildOperationExecutor.java:90)
at org.gradle.internal.operations.DelegatingBuildOperationExecutor.run(DelegatingBuildOperationExecutor.java:31)
at org.gradle.configuration.project.LifecycleProjectEvaluator$EvaluateProject.run(LifecycleProjectEvaluator.java:110)
at org.gradle.internal.operations.DefaultBuildOperationExecutor$RunnableBuildOperationWorker.execute(DefaultBuildOperationExecutor.java:300)
at org.gradle.internal.operations.DefaultBuildOperationExecutor$RunnableBuildOperationWorker.execute(DefaultBuildOperationExecutor.java:292)
at org.gradle.internal.operations.DefaultBuildOperationExecutor.execute(DefaultBuildOperationExecutor.java:174)
at org.gradle.internal.operations.DefaultBuildOperationExecutor.run(DefaultBuildOperationExecutor.java:90)
at org.gradle.internal.operations.DelegatingBuildOperationExecutor.run(DelegatingBuildOperationExecutor.java:31)
at org.gradle.configuration.project.LifecycleProjectEvaluator.evaluate(LifecycleProjectEvaluator.java:68)
at org.gradle.api.internal.project.DefaultProject.evaluate(DefaultProject.java:687)
at org.gradle.api.internal.project.DefaultProject.evaluate(DefaultProject.java:140)
at org.gradle.execution.TaskPathProjectEvaluator.configure(TaskPathProjectEvaluator.java:35)
at org.gradle.execution.TaskPathProjectEvaluator.configureHierarchy(TaskPathProjectEvaluator.java:62)
at org.gradle.configuration.DefaultBuildConfigurer.configure(DefaultBuildConfigurer.java:41)
at org.gradle.initialization.DefaultGradleLauncher$ConfigureBuild.run(DefaultGradleLauncher.java:274)
at org.gradle.internal.operations.DefaultBuildOperationExecutor$RunnableBuildOperationWorker.execute(DefaultBuildOperationExecutor.java:300)
at org.gradle.internal.operations.DefaultBuildOperationExecutor$RunnableBuildOperationWorker.execute(DefaultBuildOperationExecutor.java:292)
at org.gradle.internal.operations.DefaultBuildOperationExecutor.execute(DefaultBuildOperationExecutor.java:174)
at org.gradle.internal.operations.DefaultBuildOperationExecutor.run(DefaultBuildOperationExecutor.java:90)
at org.gradle.internal.operations.DelegatingBuildOperationExecutor.run(DelegatingBuildOperationExecutor.java:31)
at org.gradle.initialization.DefaultGradleLauncher.configureBuild(DefaultGradleLauncher.java:182)
at org.gradle.initialization.DefaultGradleLauncher.doBuildStages(DefaultGradleLauncher.java:141)
at org.gradle.initialization.DefaultGradleLauncher.executeTasks(DefaultGradleLauncher.java:124)
at org.gradle.internal.invocation.GradleBuildController$1.call(GradleBuildController.java:77)
at org.gradle.internal.invocation.GradleBuildController$1.call(GradleBuildController.java:74)
at org.gradle.internal.work.DefaultWorkerLeaseService.withLocks(DefaultWorkerLeaseService.java:154)
at org.gradle.internal.work.StopShieldingWorkerLeaseService.withLocks(StopShieldingWorkerLeaseService.java:38)
at org.gradle.internal.invocation.GradleBuildController.doBuild(GradleBuildController.java:96)
at org.gradle.internal.invocation.GradleBuildController.run(GradleBuildController.java:74)
at org.gradle.tooling.internal.provider.runner.BuildModelActionRunner.run(BuildModelActionRunner.java:55)
at org.gradle.launcher.exec.ChainingBuildActionRunner.run(ChainingBuildActionRunner.java:35)
at org.gradle.launcher.exec.ChainingBuildActionRunner.run(ChainingBuildActionRunner.java:35)
at org.gradle.tooling.internal.provider.ValidatingBuildActionRunner.run(ValidatingBuildActionRunner.java:32)
at org.gradle.launcher.exec.RunAsBuildOperationBuildActionRunner$3.run(RunAsBuildOperationBuildActionRunner.java:50)
at org.gradle.internal.operations.DefaultBuildOperationExecutor$RunnableBuildOperationWorker.execute(DefaultBuildOperationExecutor.java:300)
at org.gradle.internal.operations.DefaultBuildOperationExecutor$RunnableBuildOperationWorker.execute(DefaultBuildOperationExecutor.java:292)
at org.gradle.internal.operations.DefaultBuildOperationExecutor.execute(DefaultBuildOperationExecutor.java:174)
at org.gradle.internal.operations.DefaultBuildOperationExecutor.run(DefaultBuildOperationExecutor.java:90)
at org.gradle.internal.operations.DelegatingBuildOperationExecutor.run(DelegatingBuildOperationExecutor.java:31)
at org.gradle.launcher.exec.RunAsBuildOperationBuildActionRunner.run(RunAsBuildOperationBuildActionRunner.java:45)
at org.gradle.tooling.internal.provider.SubscribableBuildActionRunner.run(SubscribableBuildActionRunner.java:51)
at org.gradle.launcher.exec.InProcessBuildActionExecuter$1.transform(InProcessBuildActionExecuter.java:47)
at org.gradle.launcher.exec.InProcessBuildActionExecuter$1.transform(InProcessBuildActionExecuter.java:44)
at org.gradle.composite.internal.DefaultRootBuildState.run(DefaultRootBuildState.java:79)
at org.gradle.launcher.exec.InProcessBuildActionExecuter.execute(InProcessBuildActionExecuter.java:44)
at org.gradle.launcher.exec.InProcessBuildActionExecuter.execute(InProcessBuildActionExecuter.java:30)
at org.gradle.launcher.exec.BuildTreeScopeBuildActionExecuter.execute(BuildTreeScopeBuildActionExecuter.java:39)
at org.gradle.launcher.exec.BuildTreeScopeBuildActionExecuter.execute(BuildTreeScopeBuildActionExecuter.java:25)
at org.gradle.tooling.internal.provider.ContinuousBuildActionExecuter.execute(ContinuousBuildActionExecuter.java:80)
at org.gradle.tooling.internal.provider.ContinuousBuildActionExecuter.execute(ContinuousBuildActionExecuter.java:53)
at org.gradle.tooling.internal.provider.ServicesSetupBuildActionExecuter.execute(ServicesSetupBuildActionExecuter.java:62)
at org.gradle.tooling.internal.provider.ServicesSetupBuildActionExecuter.execute(ServicesSetupBuildActionExecuter.java:34)
at org.gradle.tooling.internal.provider.GradleThreadBuildActionExecuter.execute(GradleThreadBuildActionExecuter.java:36)
at org.gradle.tooling.internal.provider.GradleThreadBuildActionExecuter.execute(GradleThreadBuildActionExecuter.java:25)
at org.gradle.tooling.internal.provider.ParallelismConfigurationBuildActionExecuter.execute(ParallelismConfigurationBuildActionExecuter.java:43)
at org.gradle.tooling.internal.provider.ParallelismConfigurationBuildActionExecuter.execute(ParallelismConfigurationBuildActionExecuter.java:29)
at org.gradle.tooling.internal.provider.StartParamsValidatingActionExecuter.execute(StartParamsValidatingActionExecuter.java:59)
at org.gradle.tooling.internal.provider.StartParamsValidatingActionExecuter.execute(StartParamsValidatingActionExecuter.java:31)
at org.gradle.tooling.internal.provider.SessionFailureReportingActionExecuter.execute(SessionFailureReportingActionExecuter.java:59)
at org.gradle.tooling.internal.provider.SessionFailureReportingActionExecuter.execute(SessionFailureReportingActionExecuter.java:44)
at org.gradle.tooling.internal.provider.SetupLoggingActionExecuter.execute(SetupLoggingActionExecuter.java:46)
at org.gradle.tooling.internal.provider.SetupLoggingActionExecuter.execute(SetupLoggingActionExecuter.java:30)
at org.gradle.launcher.daemon.server.exec.ExecuteBuild.doBuild(ExecuteBuild.java:67)
at org.gradle.launcher.daemon.server.exec.BuildCommandOnly.execute(BuildCommandOnly.java:36)
at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:122)
at org.gradle.launcher.daemon.server.exec.WatchForDisconnection.execute(WatchForDisconnection.java:37)
at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:122)
at org.gradle.launcher.daemon.server.exec.ResetDeprecationLogger.execute(ResetDeprecationLogger.java:26)
at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:122)
at org.gradle.launcher.daemon.server.exec.RequestStopIfSingleUsedDaemon.execute(RequestStopIfSingleUsedDaemon.java:34)
at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:122)
at org.gradle.launcher.daemon.server.exec.ForwardClientInput$2.call(ForwardClientInput.java:74)
at org.gradle.launcher.daemon.server.exec.ForwardClientInput$2.call(ForwardClientInput.java:72)
at org.gradle.util.Swapper.swap(Swapper.java:38)
at org.gradle.launcher.daemon.server.exec.ForwardClientInput.execute(ForwardClientInput.java:72)
at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:122)
at org.gradle.launcher.daemon.server.exec.LogAndCheckHealth.execute(LogAndCheckHealth.java:55)
at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:122)
at org.gradle.launcher.daemon.server.exec.LogToClient.doBuild(LogToClient.java:62)
at org.gradle.launcher.daemon.server.exec.BuildCommandOnly.execute(BuildCommandOnly.java:36)
at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:122)
at org.gradle.launcher.daemon.server.exec.EstablishBuildEnvironment.doBuild(EstablishBuildEnvironment.java:81)
at org.gradle.launcher.daemon.server.exec.BuildCommandOnly.execute(BuildCommandOnly.java:36)
at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:122)
at org.gradle.launcher.daemon.server.exec.StartBuildOrRespondWithBusy$1.run(StartBuildOrRespondWithBusy.java:50)
at org.gradle.launcher.daemon.server.DaemonStateCoordinator$1.run(DaemonStateCoordinator.java:295)
at org.gradle.internal.concurrent.ExecutorPolicy$CatchAndRecordFailures.onExecute(ExecutorPolicy.java:63)
at org.gradle.internal.concurrent.ManagedExecutorImpl$1.run(ManagedExecutorImpl.java:46)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
at org.gradle.internal.concurrent.ThreadFactoryImpl$ManagedThreadRunnable.run(ThreadFactoryImpl.java:55)
at java.lang.Thread.run(Thread.java:745)
Caused by: org.gradle.api.GradleException: executing external native build for cmake /Users/lukesaxton/Documents/dev/AndroidSysexTest/Builds/Android/app/CMakeLists.txt
at com.android.build.gradle.internal.errors.SyncIssueHandlerImpl.reportIssue(SyncIssueHandlerImpl.kt:53)
at com.android.builder.errors.EvalIssueReporter$DefaultImpls.reportError(EvalIssueReporter.kt:122)
at com.android.build.gradle.internal.errors.SyncIssueHandler$DefaultImpls.reportError(SyncIssueHandler.kt)
at com.android.build.gradle.internal.errors.SyncIssueHandlerImpl.reportError(SyncIssueHandlerImpl.kt:30)
at com.android.build.gradle.tasks.ExternalNativeJsonGenerator.build(ExternalNativeJsonGenerator.java:203)
at com.android.build.gradle.BasePlugin.lambda$createAndroidTasks$7(BasePlugin.java:818)
at com.android.builder.profile.ThreadRecorder.record(ThreadRecorder.java:81)
at com.android.build.gradle.BasePlugin.createAndroidTasks(BasePlugin.java:806)
at com.android.build.gradle.BasePlugin.lambda$null$4(BasePlugin.java:652)
at com.android.builder.profile.ThreadRecorder.record(ThreadRecorder.java:81)
at com.android.build.gradle.BasePlugin.lambda$createTasks$5(BasePlugin.java:648)
at org.gradle.configuration.internal.DefaultListenerBuildOperationDecorator$BuildOperationEmittingAction$1$1.run(DefaultListenerBuildOperationDecorator.java:155)
at org.gradle.configuration.internal.DefaultUserCodeApplicationContext.reapply(DefaultUserCodeApplicationContext.java:58)
at org.gradle.configuration.internal.DefaultListenerBuildOperationDecorator$BuildOperationEmittingAction$1.run(DefaultListenerBuildOperationDecorator.java:152)
at org.gradle.internal.operations.DefaultBuildOperationExecutor$RunnableBuildOperationWorker.execute(DefaultBuildOperationExecutor.java:300)
at org.gradle.internal.operations.DefaultBuildOperationExecutor$RunnableBuildOperationWorker.execute(DefaultBuildOperationExecutor.java:292)
at org.gradle.internal.operations.DefaultBuildOperationExecutor.execute(DefaultBuildOperationExecutor.java:174)
at org.gradle.internal.operations.DefaultBuildOperationExecutor.run(DefaultBuildOperationExecutor.java:90)
at org.gradle.configuration.internal.DefaultListenerBuildOperationDecorator$BuildOperationEmittingAction.execute(DefaultListenerBuildOperationDecorator.java:149)
at org.gradle.internal.event.BroadcastDispatch$ActionInvocationHandler.dispatch(BroadcastDispatch.java:91)
at org.gradle.internal.event.BroadcastDispatch$ActionInvocationHandler.dispatch(BroadcastDispatch.java:80)
at org.gradle.internal.event.AbstractBroadcastDispatch.dispatch(AbstractBroadcastDispatch.java:42)
at org.gradle.internal.event.BroadcastDispatch$SingletonDispatch.dispatch(BroadcastDispatch.java:230)
at org.gradle.internal.event.BroadcastDispatch$SingletonDispatch.dispatch(BroadcastDispatch.java:149)
at org.gradle.internal.event.AbstractBroadcastDispatch.dispatch(AbstractBroadcastDispatch.java:58)
at org.gradle.internal.event.BroadcastDispatch$CompositeDispatch.dispatch(BroadcastDispatch.java:324)
at org.gradle.internal.event.BroadcastDispatch$CompositeDispatch.dispatch(BroadcastDispatch.java:234)
at org.gradle.internal.event.ListenerBroadcast.dispatch(ListenerBroadcast.java:140)
at org.gradle.internal.event.ListenerBroadcast.dispatch(ListenerBroadcast.java:37)
at org.gradle.internal.dispatch.ProxyDispatchAdapter$DispatchingInvocationHandler.invoke(ProxyDispatchAdapter.java:93)
at com.sun.proxy.$Proxy27.afterEvaluate(Unknown Source)
at org.gradle.configuration.project.LifecycleProjectEvaluator$NotifyAfterEvaluate$1.execute(LifecycleProjectEvaluator.java:187)
at org.gradle.configuration.project.LifecycleProjectEvaluator$NotifyAfterEvaluate$1.execute(LifecycleProjectEvaluator.java:184)
at org.gradle.api.internal.project.DefaultProject.stepEvaluationListener(DefaultProject.java:1418)
at org.gradle.configuration.project.LifecycleProjectEvaluator$NotifyAfterEvaluate.run(LifecycleProjectEvaluator.java:193)
... 95 more
Ok, so i’ve had another bash at this today: Following your steps and addtionally deleting the generated AndroidStudio directory (to force gradle to reconfigure), and cleaning the AS project, I managed to roll back as far as the 5.4.2 tagged commit - the sysex problem still persists there. I guess that narrows it down a bit… But I cannot convince 5.4.1 to build - just getting the SIMPLE: Error configuring error.
At this point i’ve gone nuclear on my JUCE and Android Studio installs and re-downloaded/installed everything so i’m really not sure what is going with my build environment that’s stopping me from testing with older JUCE versions on Android
Where do we go from here? I’m open to any suggestions.
The check added in 0ae5e233c was to guard against malformed sysex messages getting through in some ROLI products, but the check was a little heavy-handed and resulted in some messages being truncated or ignored in MidiDataConcatenator::processSysex() like you were seeing.