+1 thanks!
On 30.10.2015 14:26, Alex Menkov wrote: > The fix looks ok for me. > > regarda > Alex > > On 28.10.2015 21:14, Sergey Bylokhov wrote: >> Hi, Florian. >> Thanks for review! >> On 26.10.15 18:41, Florian Bomers wrote: >>> But I don't agree with "bug to bug compatiblity" and "fail fast": >>> IMHO, >>> backwards compatibility is much more important. The only exception >>> is if >>> you cannot align an important bug fix with 100% backwards >>> compatibility. >>> But removing this "catch NPE clause" is not an important bug fix. >> >> I am sure that I understand your point of view, I just want to >> highlight, that because of this silent behavior we preserve the bugs in >> the plugin code, which can cause some unpredictable issues. >> >> Well it seems there are no any other opinions, I have updated the fix, >> The catch of npe is reverted and the comment why it was added, was >> updated: >> http://cr.openjdk.java.net/~serb/8135100/webrev.04 >> >>> >>> Of course, this is a rather unimportant case. Chances are that there >>> does not exist a broken MixerProvider out in the wild. But the >>> discussion is worthwhile for setting the priorities for other bug >>> fixes >>> with similar trade-offs. >>> >>> Arguing that users can and should just remove the failing plugin >>> ignores >>> many other deployment possibilities of Java code. For example, code >>> can >>> be deployed centrally in binary form, and users don't have a choice of >>> adding, updating, or removing components on their own. Another example >>> is where users are stuck with binary code which they need but cannot >>> change anymore. For the user, knowing that a plugin is broken, is >>> not of >>> much help when she cannot fix the plugin... Also, of course, it is >>> possible that a MixerProvider only throws NPE's under certain >>> conditions >>> and works fine under other conditions. So removing that MixerProvider >>> would remove its legitimate function. >>> >>> In my opinion, updating to a new JRE should never break existing >>> applications -- if at all possible. Of course, this is my view. I >>> don't >>> know what Oracle's current policy is on this. And I don't know what >>> other incompatibilities JDK 9 will bring. But it does look to me that >>> existing service providers will still be supported. >>> >>> Thanks, >>> Florian >>> >>> >>>>> >>>>> Removing the NPE catch clause, however, will still cause a backwards >>>>> incompatibility, because if a poorly programmed MixerProvider gets >>>>> installed which throws NPE for whatever reason (might also happen >>>>> when >>>>> "info" is non-null), now AudioSystem.getMixer() will throw NPE, >>>>> where >>>>> it previously worked. >>>> >>>> But if we discuss in this way we can get an assumption that any >>>> methods of plugins can throw any type of exceptions and we should >>>> wrap >>>> them in "catch (Throwable)". I agree that we should follow the >>>> backwards compatibility as much as possible, but this case is related >>>> to "bug to bug" compatibility. For sure if we fix a bug in jdk and if >>>> some code relies on this behavior he will get an issue. But i think >>>> strategy of "fail-fast" is better, than silently ignoring the problem >>>> since a workaround should be simple as mixer removing, which is not >>>> used anyway. >>>> >>>> Note that in case of jdk9 an additional check of application's sound >>>> code will be needed, because the order of serviceloaders will be >>>> different, modules which contain providers come to play, etc. So I >>>> guess this is a good time to cleanup of our code from some >>>> workarounds >>>> which were added in jdk 1.1.*. >>>> >>>>> >>>>> I agree that it's harder for debugging mixer providers if NPE is >>>>> ignored. Other than that, I don't see any problem with keeping >>>>> the NPE >>>>> catch for backwards compatibility's sake. Even if just >>>>> theoretical... >>>>> But you never now, companies might be using poorly programmed >>>>> in-house >>>>> software or the like. >>>> >>>>> Hi, Florian. >>>>> Thanks for review! see my comments inline. >>>>> >>>>>> This is true for the included MixerProvders, but the requirement >>>>>> that >>>>>> null will return the default Mixer is just made official. We >>>>>> should, >>>>>> however, remain backwards compatible with 3rd party >>>>>> MixerProviders by >>>>>> keeping that second loop. The old style is that a MixerProvider >>>>>> returns its default Mixer as first element. Also, for backwards >>>>>> compatibility, I'd also keep the catch clause for NPE in both >>>>>> loops. >>>>> >>>>> This is tricky place, I have some thoughts about this, which I would >>>>> like to discuss. >>>>> >>>>> I studied the history to find an answer why the catch of NPE and the >>>>> second loop were added. >>>>> >>>>> - The catch of the null was added in the 1999 because of "added a >>>>> catch >>>>> for an NPE -- Netscape tends to throw this if some strings >>>>> haven't been >>>>> set in our device provider info objects". >>>>> It is actually a workaround. Because of this patch we did not catch >>>>> some >>>>> bugs in our MixerProviders. For example PortMixerProvider, >>>>> SimpleInputDeviceProvider(old mixer) were thrown NPE, when they >>>>> tried to >>>>> throw IllegalArgumentException. In the same moment the >>>>> DirectAudioDeviceProvider, HeadspaceMixerProvider(old mixer), >>>>> SoftMixingMixerProvider are ready for null. I also checked the >>>>> TMixerProvider from tritonus it also ready for null. >>>>> >>>>> >>>>> - The second loop was added in "JDK-4834461: Linux: Applet hang when >>>>> you >>>>> load it during sound card is in use". This is also a workaround >>>>> for a >>>>> situation when we try to get a default mixer in the first loop >>>>> but it >>>>> was not available for some reason, in this case we will return first >>>>> mixer from the first mixer provider. But the second loop will be run >>>>> only if the first loop will not find the default mixer in some other >>>>> providers. >>>>> >>>>> So imagine this situation when some old 3rd party MixerProvider is >>>>> used: >>>>> - The user sets some provider, which throw the NPE on null in >>>>> getMixer(); >>>>> - The first loop call this provider and skip it in catch block >>>>> - The next bundled provider will be used instead of user's mixer, >>>>> the >>>>> second loop is not executed. >>>>> - If we use this approach the user will not be able to check that >>>>> wrong >>>>> provider is in use, and in case of NPE the temporary workaround >>>>> will be >>>>> - removing of custom mixer provider which are not used anyway. >>>>> >>>>> Note that in jdk9 the "META-INF/services" will not be used, so there >>>>> will be no option to remove bundled providers via configs, and we >>>>> will >>>>> always iterate over the bundled providers in the first loop. >>>>> >>>>> For the case of some other vendors of jdk, after the moment of >>>>> specification clarification all default providers should not >>>>> contradict >>>>> the specification, and should not throw NPE in getMixer(), but >>>>> return >>>>> default mixer. >>>>> >>>>> Does it make sense? >>>>> >>>>>> >>>>>> >>>>>> [1] https://bugs.openjdk.java.net/browse/JDK-4834461 >>>>>> >>>>>> >>>>>> On 08.10.15 11:46, Florian Bomers wrote: >>>>>>>> For me the most logical is to return default playback mixer :) >>>>>>> >>>>>>> yes, at the time it was most important to provide an easy way to >>>>>>> get a >>>>>>> playback device. >>>>>>> >>>>>>> Can you send a new webrev? >>>>>>> Thanks, >>>>>>> Florian >>>>>>> >>>>>>> >>>>>>> On 25.09.2015 20:33, alexey menkov wrote: >>>>>>>> >>>>>>>> >>>>>>>> On 25.09.2015 20:42, Sergey Bylokhov wrote: >>>>>>>>> On 25.09.15 20:32, alexey menkov wrote: >>>>>>>>>> Ok, lets only clarify MixerProvider.getMixer(null) behavior. >>>>>>>>>> Actually AusioSystem.getMixer(null) looks unclear because >>>>>>>>>> unclear >>>>>>>>>> what >>>>>>>>>> is the "default mixer" in the case (we may have different >>>>>>>>>> "default >>>>>>>>>> playback mixer", "default recording mixer", "default port >>>>>>>>>> mixer"). >>>>>>>>> >>>>>>>>> Right, if to consider that the sequence of providers isn't >>>>>>>>> specified, >>>>>>>>> then it is unclear what this method should actually return. I do >>>>>>>>> not >>>>>>>>> understand the purpose to return some random mixer. I think that >>>>>>>>> intention was to return "default playback mixer"? >>>>>>>> >>>>>>>> I don't know. I suppose this is ancient method (and most likely >>>>>>>> nobody >>>>>>>> use it) and the implementation was changed this way to get >>>>>>>> DirectAudioDevice as default (it supports both playback and >>>>>>>> recording). >>>>>>>> For me the most logical is to return default playback mixer :) >>>>>>>> >>>>>>>> --alex >>>>>>>> >>>>>>>>> >>>>>>>>>> >>>>>>>>>> regards >>>>>>>>>> Alex >>>>>>>>>> >>>>>>>>>> On 25.09.2015 18:41, Sergey Bylokhov wrote: >>>>>>>>>>> Hi, Alexey. >>>>>>>>>>> Thanks for review! see my comments inline. >>>>>>>>>>> >>>>>>>>>>> On 25.09.15 18:23, alexey menkov wrote: >>>>>>>>>>>> Hi Sergey, >>>>>>>>>>>> >>>>>>>>>>>> Overall looks good, but I don't like change in >>>>>>>>>>>> MixerProvider.getMixer >>>>>>>>>>>> and PortMixerProvider.getMixer. >>>>>>>>>>>> >>>>>>>>>>>> MixerProvider.getMixer(null) is used by >>>>>>>>>>>> AudioSystem.getMixer(null) (to >>>>>>>>>>>> get the default mixer), but provide PortMixer as the default >>>>>>>>>>>> does >>>>>>>>>>>> not >>>>>>>>>>>> look good, I'd expect AudioSystem.getMixer(null) returns some >>>>>>>>>>>> playback-able device. (Note also that for Ports >>>>>>>>>>>> "SourceDataLine" >>>>>>>>>>>> means >>>>>>>>>>>> controls for recording device) >>>>>>>>>>> >>>>>>>>>>>> >>>>>>>>>>>> Also comment for MixerProvider.getMixer(Mixer.Info): >>>>>>>>>>>> > * @param info an info object that describes the desired >>>>>>>>>>>> mixer, >>>>>>>>>>>> > * or {@code null} for the system default mixer >>>>>>>>>>>> >>>>>>>>>>>> is unclear and is not consistent with the description above: >>>>>>>>>>>> > * The full set of the mixer info objects that >>>>>>>>>>>> represent the >>>>>>>>>>>> mixers >>>>>>>>>>>> > * supported by this {@code MixerProvider} may be obtained >>>>>>>>>>>> through >>>>>>>>>>>> the >>>>>>>>>>>> > * {@code getMixerInfo} method. Use the {@code >>>>>>>>>>>> isMixerSupported} >>>>>>>>>>>> method to >>>>>>>>>>>> > * test whether this {@code MixerProvider} supports a >>>>>>>>>>>> particular >>>>>>>>>>>> mixer. >>>>>>>>>>>> It looks like MixerProvider.getMixerInfo should add "null" to >>>>>>>>>>>> the >>>>>>>>>>>> supported mixers and MixerProvider.isMixerSupported(null) >>>>>>>>>>>> should >>>>>>>>>>>> return >>>>>>>>>>>> "true". >>>>>>>>>>> >>>>>>>>>>> In this case the null means that some default mixer will be >>>>>>>>>>> returned. I >>>>>>>>>>> am not sure that isMixerSupported(null) should return true, >>>>>>>>>>> instead I >>>>>>>>>>> can clarify the specification of getMixer(null), and mention >>>>>>>>>>> that if >>>>>>>>>>> null is provided then this mixer will try to return some >>>>>>>>>>> default( >>>>>>>>>>> supported) mixer if possible, otherwise >>>>>>>>>>> IllegalArgumentException >>>>>>>>>>> will be >>>>>>>>>>> thrown. >>>>>>>>>>> >>>>>>>>>>> For the case of PortMixerProvider and "null" I can throw a >>>>>>>>>>> IllegalArgumentException which will mean that this provider do >>>>>>>>>>> not >>>>>>>>>>> have >>>>>>>>>>> "default" mixer. >>>>>>>>>>> >>>>>>>>>>>> >>>>>>>>>>>> For now I don't have a proposal how to fix this. >>>>>>>>>>>> Maybe it would be better to fix behavior of >>>>>>>>>>>> AudioSystem.getMixer(null) - >>>>>>>>>>>> now it ignores "sound.properties" file (see AudioSystem >>>>>>>>>>>> spec for >>>>>>>>>>>> explanations). >>>>>>>>>>>> >>>>>>>>>>>> regards >>>>>>>>>>>> Alex >>>>>>>>>>>> >>>>>>>>>>>> On 14.09.2015 16:29, Sergey Bylokhov wrote: >>>>>>>>>>>>> Hello Audio Guru. >>>>>>>>>>>>> >>>>>>>>>>>>> Please review the fix for jdk9. This issue is a subtask of: >>>>>>>>>>>>> 4912693: Behavior of null arguments not specified in Java >>>>>>>>>>>>> Sound >>>>>>>>>>>>> >>>>>>>>>>>>> In this patch I cover the whole javax.sound.sampled.spi >>>>>>>>>>>>> package. >>>>>>>>>>>>> >>>>>>>>>>>>> The small description of the fix: >>>>>>>>>>>>> - I have checked all methods in the spi package and all >>>>>>>>>>>>> related >>>>>>>>>>>>> methods >>>>>>>>>>>>> in AudioSystem class. >>>>>>>>>>>>> - I have moved related tests to the folder corresponding the >>>>>>>>>>>>> package >>>>>>>>>>>>> and >>>>>>>>>>>>> class name. >>>>>>>>>>>>> - I have written a tests for every method and class which I >>>>>>>>>>>>> changed. >>>>>>>>>>>>> Note that these classes related to the different service >>>>>>>>>>>>> providers, >>>>>>>>>>>>> so I >>>>>>>>>>>>> have covered all installed implementations of each provider. >>>>>>>>>>>>> >>>>>>>>>>>>> >>>>>>>>>>>>> Long description. >>>>>>>>>>>>> I splits the fix to 3 use cases: >>>>>>>>>>>>> - If the method always throw a NPE, then I simply update a >>>>>>>>>>>>> javadoc and >>>>>>>>>>>>> write a small test. >>>>>>>>>>>>> - If the method most of the time throw a NPE then I update a >>>>>>>>>>>>> javadoc >>>>>>>>>>>>> and >>>>>>>>>>>>> change the method to always throw a NPE. Also I write a test >>>>>>>>>>>>> which >>>>>>>>>>>>> tries >>>>>>>>>>>>> to emulate both cases when NPE was thrown and when not. For >>>>>>>>>>>>> example >>>>>>>>>>>>> AudioFileWriter.isFileTypeSupported(Type) always throws a >>>>>>>>>>>>> NPE >>>>>>>>>>>>> if at >>>>>>>>>>>>> least one type is supported, but if the array is empty then >>>>>>>>>>>>> false is >>>>>>>>>>>>> returned. >>>>>>>>>>>>> - If the method have a few parameters and throw a NPE for >>>>>>>>>>>>> some >>>>>>>>>>>>> set of >>>>>>>>>>>>> them. For example AudioFloatFormatConverter. >>>>>>>>>>>>> isConversionSupported(Encoding,AudioFormat), the appropriate >>>>>>>>>>>>> test >>>>>>>>>>>>> tries >>>>>>>>>>>>> to cover these cases. >>>>>>>>>>>>> >>>>>>>>>>>>> It turned out that all methods throw a NPE except of one: >>>>>>>>>>>>> AudioSystem.getMixer()(MixerProvider.getMixer()), but it was >>>>>>>>>>>>> found >>>>>>>>>>>>> that >>>>>>>>>>>>> the specification of MixerProvider.getMixer has no >>>>>>>>>>>>> information >>>>>>>>>>>>> about >>>>>>>>>>>>> the >>>>>>>>>>>>> null, so I copied it from the AudioSystem.getMixer(). >>>>>>>>>>>>> Also one >>>>>>>>>>>>> implementation of MixerProvider - >>>>>>>>>>>>> PortMixerProvider.getMixer() >>>>>>>>>>>>> throws >>>>>>>>>>>>> NPE, so updated its implementation to the same as >>>>>>>>>>>>> DirectAudioDeviceProvider.getMixer(); >>>>>>>>>>>>> >>>>>>>>>>>>> I have done all related regression/jck/sqe tests, and I >>>>>>>>>>>>> found >>>>>>>>>>>>> one >>>>>>>>>>>>> issue >>>>>>>>>>>>> in jck and regression tests. Both are related to JDK-4941629 >>>>>>>>>>>>> [1] >>>>>>>>>>>>> (see >>>>>>>>>>>>> comments in this CR). The jck test assumes that the method >>>>>>>>>>>>> AudioSystem.write(ais, null, stream) should throw >>>>>>>>>>>>> IllegalArgumentException. But according to specification it >>>>>>>>>>>>> should >>>>>>>>>>>>> throw >>>>>>>>>>>>> IllegalArgumentException if the type is unsupported, but the >>>>>>>>>>>>> related >>>>>>>>>>>>> method AudioSystem.isFileTypeSupported(Type) will always >>>>>>>>>>>>> throw >>>>>>>>>>>>> a NPE >>>>>>>>>>>>> for null. I prefer to file a bug against jck for this case. >>>>>>>>>>>>> >>>>>>>>>>>>> >>>>>>>>>>>>> [1] https://bugs.openjdk.java.net/browse/JDK-4941629 >>>>>>>>>>>>> >>>>>>>>>>>>> Bug: https://bugs.openjdk.java.net/browse/JDK-8135100 >>>>>>>>>>>>> The new test: >>>>>>>>>>>>> http://cr.openjdk.java.net/~serb/8135100/webrev.01 >>>>>>>>>>>>> >>>>>>>>>>> >>>>>>>>>>> >>>>>>>>> >>>>>>>>> >>>>>>>> >>>>>>> >>>>>> >>>>>> >>>>> >>>>> >>>> >>>> >>>> >>>> -- >>>> Florian Bomers >>>> Bome Software >>>> >>>> everything sounds. >>>> http://www.bome.com >>>> __________________________________________________________________ >>>> Bome Software GmbH & Co KG Gesellschafterin: >>>> Dachauer Str.187 Bome Komplementär GmbH >>>> 80637 München, Germany Geschäftsführung: Florian Bömers >>>> Amtsgericht München HRA95502 Amtsgericht München HRB185574 >>>> >> >> > -- Florian Bomers Bome Software everything sounds. http://www.bome.com __________________________________________________________________ Bome Software GmbH & Co KG Gesellschafterin: Dachauer Str.187 Bome Komplementär GmbH 80637 München, Germany Geschäftsführung: Florian Bömers Amtsgericht München HRA95502 Amtsgericht München HRB185574