Closed alwin-joseph closed 2 years ago
I believe so. See https://www.w3.org/Daemon/User/Installation/PrivilegedPorts.html
Nope. The intention of this tests is to proof that auto-selection is working well. So they MUST use port 0.
Nope. The intention of this tests is to proof that auto-selection is working well. So they MUST use port 0.
Ok. In that case what additional change is required for passing the test in non-Windows machines. Should there be a test change to allow non root users to have access to all ports ? Or are the implementations expected to fix this at their end for accomplishing the auto-selection.
JAX-RS does not restrict the algorithm or port range in any way, it simply instructs the tested product to pick a free port of its own choice. If the tested product decides to start on a port that actually is restricted, the vendor should either take care to run the TCK as admin always, or change the product implementation to pick a non-restricted port instead. This has nothing to do with JAX-RS, neither the API, spec nor TCK, but solely with what the vendor wants it to happen.
It is not an implementation that picks the port, it is the test. I thought about some modification such as (assumingly the same port is not chosen again and again):
private static final int someFreeIpPort() throws IOException {
int port = 0;
while (port < 1024) {
try (final ServerSocket serverSocket = new ServerSocket(0)) {
port = serverSocket.getLocalPort();
}
}
return port;
}
I agree that it is odd that a restricted port is chosen.
Just remember, we run the TCK in the Eclipse CI. We cannot use admin privileges there.
It is not an implementation that picks the port, it is the test.
Good catch! I actually missed that!
I think it is best to fix it in the way you proposed -- even if I think that it actually should be fixed by the JRE...
Maybe it would be a good idea to refactor this method so other tests can make use of it, too?
Good idea. There is a util folder for common utility methods, it can be used for methods like this.
Good, so I will do that.
With PR #1090 the TCK test now uses a utility method that will bear an unprivileged IP port. Note that this only fixed the TCK test. For ports discovered by implementations, still it is up to the implementation to fix the same problem (unless already done).
I also filed bug report JDK-8280919 for this weird / inconsistent JRE behavior.
I see the modified someFreeIpPort() method in PR https://github.com/eclipse-ee4j/jaxrs-api/pull/1090 is not used for below failing tests : SeBootstrapIT.shouldBootInstanceUsingDefaults SeBootstrapIT.shouldBootInstanceUsingImplementationsDefaultIpPort
Does these tests use ports discovered by implementations?
These tests still fail for me when run against jersey-3.1.0-M2 .
Both tests deliverately instruct the implementation to chose the port, so it is up to the vendor of the tested implementation to either solve this problem within his product. Please also follow the discussion of the actual cause JRE-8280919: They ask for a check on the original causing host. @alwin-joseph Please provide the needed information to the OpenJDK team. Thanks.
Hi Markus -
I think there are 2 issues here :
AFAIS both of these tests do not use any custom method to obtain a free unprivileged IP port and hence do not use ServerSocket(0). (Please correct me if wrong). The issues are at these lines:
For test shouldBootInstanceUsingImplementationsDefaultIpPort I used port 1030 instead of SeBootstrap.Configuration.DEFAULT_PORT
as below and it passed (it breaks the intention of the test, but I was just checking)
final SeBootstrap.Configuration requestedConfiguration = bootstrapConfigurationBuilder.protocol("HTTP")
.host("localhost").port(1030).rootPath("/root/path").build();
Hi @jansupol Are the ports chosen by Jersey/vendor here when SeBootstrap.Configuration.DEFAULT_PORT
is chosen as the port number ?
~Jersey depends on Grizzly to choose the port if -1. We may change this for M3.~
Eh wrong. Jersey uses 443 for HTTPS and 80 for HTTP when starting Grizzly with -1.
In fact this proofs that the test itself is correct! The problem you experience is that Jersey intentionally chooses privileged ports 443/80 by default. To pass the tests on you machine, either the machine must allow that or Jersey must use unprivileged defaults.
As this is not a bug of the TCK but a problem of the specific execution environment and product under test, can we close this issue? The solution either is (a) fixing the bug in the JRE, (b) fixing the bug in the tested product, or (c) using containers for testing so root in the test is not root on the host.
2. Some Bootstrap tests that uses someFreeIpPort()/unprivilegedPort()/ServerSocket(0) method to get a free unprivileged port. The PR [Fixed #1088 #1090](https://github.com/eclipse-ee4j/jaxrs-api/pull/1090) covers this but I have not seen any issue with these tests yet. I have not been able to confirm myself that ServerSocket(0) returns a port < 1024 too.
Hi Markus - Just highlighting this again.
The 2 failing tests does not use someFreeIpPort()/unprivilegedPort()/ServerSocket(0) method. I do not see any issue with the ServerSocket/JRE here as those tests using it in the TCK are passing. Infact I could see that ServerSocket returned port >1024 for the other tests at least when I tried. Hence I cannot reproduce or justify the JDK bug you created. Apologies if I was not explicit earlier.
My concern was only the 2 failing tests which uses default ports and not the port number generated by someFreeIpPort(). The solutions for these 2 failing tests are probably
(b) fixing the bug in the tested product, or (c) using containers for testing so root in the test is not root on the host.
and not
(a) fixing the bug in the JRE
@alwin-joseph I need to disagree.
FREE_PORT: The intention of this test is to proof that the tested product will start correctly when the product selected a free port of its own choice. Apparently the tested product choose a port on which it actually cannot run on that host, so the TCK test fails deliberately to proof that the product selects a wrong port. The default port (zero) instructs the JRE (via the tested product, here: Jersey via Grizzly) to auto-select a free port by using ServerSocket(0) internally (inside Grizzly). I cannot see why it shall not be a bug of the JRE that the JRE returns a privileged port. Can you please elaborate why you think that it is fine for the JRE to return a privileged port to Grizzly on that host while the OpenJDK team accepts that this is a bug of the JRE? So can you please provided the information to the OpenJDK team requested in https://bugs.openjdk.java.net/browse/JDK-8280919?
DEFAULT_PORT: The intention of this test is to proof that the tested product will start correctly when the product selected its own default port of its own choice. Neither the TCK nor the JAX-RS Spec mandate that privileged ports neither MUST nor SHOULD be privileged ports. The tested product (here: Jersey via GlassFish) deliberately uses privileged ports here to be RFC compliant. It is the product's decision to use 443/80, and it is not a bug at all. To make that test run on that particular host, either Jersey needs explicit configuration outside of this TCK test so it will choose a different default port, or the person that wants to run the TCK against Jersey on that machine has to configure that machine to use containers. It is not something to be changed by the TCK, as the TCK test deliberatey fails here to proof that Jersey cannot run in this environment because Jersey selected an invalid default port on that machine.
I hope it is clear now that both has nothing to do with the TCK, but only with either the JRE, Jersey or the particular machine you run the test on.
Sorry I had few more questions.
- FREE_PORT: The intention of this test is to proof that the tested product will start correctly when the product selected a free port of its own choice. Apparently the tested product choose a port on which it actually cannot run on that host, so the TCK test fails deliberately to proof that the product selects a wrong port.
Can you please list which are those tests in SeBootstrapIT where the product will select a free port of its own choice and failed with Jersey (before PR 1090)?
The default port (zero) instructs the JRE (via the tested product, here: Jersey via Grizzly) to auto-select a free port by using ServerSocket(0) internally (inside Grizzly). I cannot see why it shall not be a bug of the JRE that the JRE returns a privileged port. Can you please elaborate why you think that it is fine for the JRE to return a privileged port to Grizzly on that host while the OpenJDK team accepts that this is a bug of the JRE? So can you please provided the information to the OpenJDK team requested in https://bugs.openjdk.java.net/browse/JDK-8280919?
I agree that if ServerSocket(0) returns a privileged port then it is an unexpected behaviour(JRE bug). But I haven't been able to reproduce this case.
- DEFAULT_PORT: The intention of this test is to proof that the tested product will start correctly when the product selected its own default port of its own choice. Neither the TCK nor the JAX-RS Spec mandate that privileged ports neither MUST nor SHOULD be privileged ports. The tested product (here: Jersey via GlassFish) deliberately uses privileged ports here to be RFC compliant. It is the product's decision to use 443/80, and it is not a bug at all. To make that test run on that particular host, either Jersey needs explicit configuration outside of this TCK test so it will choose a different default port, or the person that wants to run the TCK against Jersey on that machine has to configure that machine to use containers. It is not something to be changed by the TCK, as the TCK test deliberatey fails here to proof that Jersey cannot run in this environment because Jersey selected an invalid default port on that machine.
Agree on this. From what I understand below are the two tests where the product selects default port of its choice. -shouldBootInstanceUsingDefaults -shouldBootInstanceUsingImplementationsDefaultIpPort These tests do not use ServerSocket indirectly or directly, instead the ports 443/80 are chosen by Jersey here and hence they fail. Please correct me if otherwise.
- FREE_PORT: The intention of this test is to proof that the tested product will start correctly when the product selected a free port of its own choice. Apparently the tested product choose a port on which it actually cannot run on that host, so the TCK test fails deliberately to proof that the product selects a wrong port.
Can you please list which are those tests in SeBootstrapIT where the product will select a free port of its own choice and failed with Jersey (before PR 1090)?
I cannot tell you where Jersey failed as I did not test Jersey but you did. So I tell you the tests where any tested implementation could fail due to selecting a free port. This is at least SeBootstrapIT::shouldBootInstanceUsingSelfDetectedFreeIpPort
, as it enforces the selection of a free port by the tested implementation. In case the tested implementation does not have statically fixed defaults but instead opts for dynamically selecting a free port as its default, also SeBootstrapIT::shouldBootInstanceUsingDefaults
and SeBootstrapIT::shouldBootInstanceUsingImplementationsDefaultIpPort
as both ask the tested implementation to use its defaults (the first one implicitly by not specifying a port, the second one explicitly by specifying DEFAULT_PORT
).
The default port (zero) instructs the JRE (via the tested product, here: Jersey via Grizzly) to auto-select a free port by using ServerSocket(0) internally (inside Grizzly). I cannot see why it shall not be a bug of the JRE that the JRE returns a privileged port. Can you please elaborate why you think that it is fine for the JRE to return a privileged port to Grizzly on that host while the OpenJDK team accepts that this is a bug of the JRE? So can you please provided the information to the OpenJDK team requested in https://bugs.openjdk.java.net/browse/JDK-8280919?
I agree that if ServerSocket(0) returns a privileged port then it is an unexpected behaviour(JRE bug). But I haven't been able to reproduce this case.
You should have, as this is what actually caused your test drive to fail in the first place.
- DEFAULT_PORT: The intention of this test is to proof that the tested product will start correctly when the product selected its own default port of its own choice. Neither the TCK nor the JAX-RS Spec mandate that privileged ports neither MUST nor SHOULD be privileged ports. The tested product (here: Jersey via GlassFish) deliberately uses privileged ports here to be RFC compliant. It is the product's decision to use 443/80, and it is not a bug at all. To make that test run on that particular host, either Jersey needs explicit configuration outside of this TCK test so it will choose a different default port, or the person that wants to run the TCK against Jersey on that machine has to configure that machine to use containers. It is not something to be changed by the TCK, as the TCK test deliberatey fails here to proof that Jersey cannot run in this environment because Jersey selected an invalid default port on that machine.
Agree on this. From what I understand below are the two tests where the product selects default port of its choice. -shouldBootInstanceUsingDefaults -shouldBootInstanceUsingImplementationsDefaultIpPort These tests do not use ServerSocket indirectly or directly, instead the ports 443/80 are chosen by Jersey here and hence they fail. Please correct me if otherwise.
Correct.
- FREE_PORT: The intention of this test is to proof that the tested product will start correctly when the product selected a free port of its own choice. Apparently the tested product choose a port on which it actually cannot run on that host, so the TCK test fails deliberately to proof that the product selects a wrong port.
Can you please list which are those tests in SeBootstrapIT where the product will select a free port of its own choice and failed with Jersey (before PR 1090)?
I cannot tell you where Jersey failed as I did not test Jersey but you did. So I tell you the tests where any tested implementation could fail due to selecting a free port. This is at least
SeBootstrapIT::shouldBootInstanceUsingSelfDetectedFreeIpPort
, as it enforces the selection of a free port by the tested implementation.
This test and all others except the SeBootstrapIT::shouldBootInstanceUsingDefaults
and SeBootstrapIT::shouldBootInstanceUsingImplementationsDefaultIpPort
passed when I ran with Jersey.
In case the tested implementation does not have statically fixed defaults but instead opts for dynamically selecting a free port as its default, also
SeBootstrapIT::shouldBootInstanceUsingDefaults
andSeBootstrapIT::shouldBootInstanceUsingImplementationsDefaultIpPort
as both ask the tested implementation to use its defaults (the first one implicitly by not specifying a port, the second one explicitly by specifyingDEFAULT_PORT
).
Are you saying that even when these 2 tests - SeBootstrapIT::shouldBootInstanceUsingDefaults
and SeBootstrapIT::shouldBootInstanceUsingImplementationsDefaultIpPort
- are run that could mean a free port is used when statically fixed defaults are not present and hence the failure of these 2 tests could mean issue with ServerSocket(0) within the implementation ?
But Jersey does have default ports 443/80 specified (as mentioned before) hence IMO shouldBootInstanceUsingDefaults & shouldBootInstanceUsingImplementationsDefaultIpPort
are not using ServerSocket(0). Am I right ?
The default port (zero) instructs the JRE (via the tested product, here: Jersey via Grizzly) to auto-select a free port by using ServerSocket(0) internally (inside Grizzly). I cannot see why it shall not be a bug of the JRE that the JRE returns a privileged port. Can you please elaborate why you think that it is fine for the JRE to return a privileged port to Grizzly on that host while the OpenJDK team accepts that this is a bug of the JRE? So can you please provided the information to the OpenJDK team requested in https://bugs.openjdk.java.net/browse/JDK-8280919?
I agree that if ServerSocket(0) returns a privileged port then it is an unexpected behaviour(JRE bug). But I haven't been able to reproduce this case.
You should have, as this is what actually caused your test drive to fail in the first place.
The only failure I reported were the tests shouldBootInstanceUsingDefaults & shouldBootInstanceUsingImplementationsDefaultIpPort
for which I assumed the privileged ports 443/80 were direclty used as defaults from Jersey.
In case the tested implementation does not have statically fixed defaults but instead opts for dynamically selecting a free port as its default, also
SeBootstrapIT::shouldBootInstanceUsingDefaults
andSeBootstrapIT::shouldBootInstanceUsingImplementationsDefaultIpPort
as both ask the tested implementation to use its defaults (the first one implicitly by not specifying a port, the second one explicitly by specifyingDEFAULT_PORT
).Are you saying that even when these 2 tests -
SeBootstrapIT::shouldBootInstanceUsingDefaults
andSeBootstrapIT::shouldBootInstanceUsingImplementationsDefaultIpPort
- are run that could mean a free port is used when statically fixed defaults are not present and hence the failure of these 2 tests could mean issue with ServerSocket(0) within the implementation ?
Yes, the JAX-RS Bootstrap API allows such a behaviour. Having said that, IIUC what @jansupol told us, then Jersey de-facto will never do that but always use 443/80. But as this is a JAX-RS TCK discussion and not a Jersey discussion, I need to explain the whole truth.
But Jersey does have default ports 443/80 specified (as mentioned before) hence IMO
shouldBootInstanceUsingDefaults & shouldBootInstanceUsingImplementationsDefaultIpPort
are not using ServerSocket(0). Am I right ?
I confirm this is what @jansupol told us.
The only failure I reported were the tests
shouldBootInstanceUsingDefaults & shouldBootInstanceUsingImplementationsDefaultIpPort
for which I assumed the privileged ports 443/80 were direclty used as defaults from Jersey.
@spericas @jansupol So why did you ask me to change the TCK code to guarantee that this won't happen?
@spericas @jansupol So why did you ask me to change the TCK code to guarantee that this won't happen?
I was likely @jansupol. I believe he is on vacation this week.
So how to proceed? I'd like to propose that I undo the unnecessary port checks, as that case never happend on any machine. Counterproposals?
@jansupol Can you can comment on this issue?
I can say RESTEasy is passing the SeBootstrapIT
as it is now. The test seems fine to me.
Jersey 3.1.0-M3 does not use privileged ports any longer, ports 8080 and 8443 are used instead.
Okay so as it is not actually needed, I will remove the explicit port number check again.
Jersey 3.1.0-M3 does not use privileged ports any longer, ports 8080 and 8443 are used instead.
Off-Topic: Is there a public Maven repo where I can pull Jersey 3.1.0-M3 from?
It's in the default staging repo for Jakarta / EE4J projects:
As PR #1103 is merge, I think we can close this issue?
Issue fixed in Jersey 3.1 M3 version
2 below SeBootstrapIT tests fail when run in Linux and Mac for Jersey(M2)
with the below errors.
The tests were reported as passing in Windows.
The issue was fixed by running
sudo /sbin/sysctl -w net.ipv4.ip_unprivileged_port_start=0
in linux machine to allow non root users to have access to all ports. Is there any change required in the test code to get the test pass without the above workaround? Should we be using a port number >1024 to run these 2 tests?@mkarg @jansupol @spericas