Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[JENKINS-46386] - Detach ServletContext logic to a pluggable Provider #3065

Conversation

oleg-nenashev
Copy link
Member

It should prevent classloading issues on agents for sure. The implementation is a bit hackish, ideally providers should be somehow integrated into the Jenkins object singleton (though then we need to prevent variable usage before Jenkins' full initialization)

No autotests so far, because it requires specification of a custom web.xml for the WAR file. Will tests the case manually

See JENKINS-46386.

Proposed changelog entries

  • Bug: JENKINS-46386 - Prevent failure of custom agent types with javax.servlet.ServletContextListenerclassloading issues. Now the class is not being propagated to agents
  • ...

Submitter checklist

  • JIRA issue is well described
  • Changelog entry appropriate for the audience affected by the change (users or developer, depending on the change). Examples
    * Use the Internal: prefix if the change has no user-visible impact (API, test frameworks, etc.)
  • Appropriate autotests or explanation to why this change has no tests
  • For dependency updates: links to external changelogs and, if possible, full diffs

Desired reviewers

@reviewbybees @KostyaSha

It should prevent classloading issues on agents for sure.
@ghost
Copy link

ghost commented Oct 9, 2017

This pull request originates from a CloudBees employee. At CloudBees, we require that all pull requests be reviewed by other CloudBees employees before we seek to have the change accepted. If you want to learn more about our process please see this explanation.

@daniel-beck daniel-beck self-requested a review October 9, 2017 11:56
@oleg-nenashev oleg-nenashev requested a review from jtnord October 9, 2017 15:40

//TODO: This should use the annotation indexer at least.
// Ideally it should be a part of the Jenkins singleton in order to play nicely with {@code JenkinsRule}.
private static final CopyOnWriteMap<String, SystemPropertiesProvider> providers = new CopyOnWriteMap.Hash<>();
Copy link
Member

@jtnord jtnord Oct 9, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the map symatics are not really unused - you could remove using the actual provider (object) to remove and use a standard CopyOnWrite collection.

Ontop of this you get different (random) iteration order (the CopyOnWriteMap makes no guarantees about ordering). so could get hard to reproduce bugs when you sometimes get a system property and other times get a ServletContext parameter...

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, probably Map is not required. I just added it to support Removal, but there are more simple and efficient ways for sure

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Well, this is all restricted, and there is no removal, so KISS.

Copy link
Member

@jtnord jtnord left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

left a comment about what looks like a bug inline.

ontop of this I wonder if anyone really uses this functionality. Would a flat properties file in JENKINS_HOME (CWD of the agent) not be much better and would work on agents and masters alike?

(OT) The fact the jenkins changes behaviour based on unversioned environment variables also troubles me (I still see people starting services with /etc/initi.d/servericec start... which will not start with a clean environment but whatever the current user has polluted their env with to begin with

@oleg-nenashev
Copy link
Member Author

ontop of this I wonder if anyone really uses this functionality. Would a flat properties file in JENKINS_HOME (CWD of the agent) not be much better and would work on agents and masters alike?

Yes, I confirm I use these settings to customize the Jenkins behavior from my custom Jenkins WAR packaging. More in the private chat.

The fact the jenkins changes behaviour based on unversioned environment variables also troubles me

I suggest filing a ticket

@oleg-nenashev oleg-nenashev added the work-in-progress The PR is under active development, not ready to the final review label Oct 9, 2017
@oleg-nenashev
Copy link
Member Author

I need to fix the test codebase. Yes, I will try compiling it on my machine next time...

@oleg-nenashev oleg-nenashev added needs-more-reviews Complex change, which would benefit from more eyes and removed work-in-progress The PR is under active development, not ready to the final review labels Oct 13, 2017
@jglick
Copy link
Member

jglick commented Oct 16, 2017

The broader issue is that #3067 lacked a test because

  • agents will only be unable to load javax.servlet.* under certain servlet containers or environments, IIUC
  • Jenkins fails to block RemoteClassLoader from even trying to load such classes under normal conditions
  • thus, routine test suites which do simple stuff on agents pass despite the bug

This is long filed in JIRA and I would rather prioritize a fix of that so we are not making speculative and untestable fixes.

@oleg-nenashev
Copy link
Member Author

Yes, even on the wild the issue happens rarely. @KostyaSha got a reproducible scenario in YAD, but I was using the plugin easily for many containers without an issue. ATH does not catches it as well. @jglick are you fine with the current fix PoC in this PR?

For sure, we need to make the classloading logic more efficient + maybe add some static analysis around the OnMaster interface. It's not the only place in the code we may get into such misbehavior, unfortunately.

@jglick jglick self-requested a review October 26, 2017 15:42
Copy link
Member

@jglick jglick left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A bit overengineered, and still does nothing to block us from making the broader category of mistakes in the future (nor is there any test proving that the fix works), but seems to be a step in the right direction.

*/
@Override
@SuppressFBWarnings(value = "ST_WRITE_TO_STATIC_FROM_INSTANCE_METHOD",
justification = "Currently Jenkins instance may have one ond only one context")
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

typo

* The ServletContext to get the "init" parameters from.
*/
@CheckForNull
private static ServletContext theContext;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why is this static?

* @see ServletContextSystemPropertiesProvider
*/
@Restricted(NoExternalUse.class)
public abstract class SystemPropertiesProvider {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This and ServletContextSystemPropertiesProvider could have just have been nested classes of SystemProperties, I think; would be more readable.


//TODO: This should use the annotation indexer at least.
// Ideally it should be a part of the Jenkins singleton in order to play nicely with {@code JenkinsRule}.
private static final CopyOnWriteMap<String, SystemPropertiesProvider> providers = new CopyOnWriteMap.Hash<>();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Well, this is all restricted, and there is no removal, so KISS.

* Gets all registered providers.
* @return Collection of registered providers.
*/
public static Collection<SystemPropertiesProvider> all() {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

unused

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Restricted anyway

* @return Removed provider (if any)
*/
@CheckForNull
public static SystemPropertiesProvider removeProvider(@Nonnull Class<?> providerClass) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

unused

@Before
public void setUp() {
// Does not matter what we call, the fields are static
new ServletContextSystemPropertiesProvider().contextInitialized(new ServletContextEvent(j.jenkins.servletContext));
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why would this not be called automatically by Jetty during JenkinsRule setup?

@jglick
Copy link
Member

jglick commented Oct 27, 2017

Except:

Write to static field jenkins.util.ServletContextSystemPropertiesProvider.theContext from instance method jenkins.util.ServletContextSystemPropertiesProvider.contextDestroyed(ServletContextEvent) [jenkins.util.ServletContextSystemPropertiesProvider] At ServletContextSystemPropertiesProvider.java:[line 66] ST_WRITE_TO_STATIC_FROM_INSTANCE_METHOD

as I noted.

@oleg-nenashev oleg-nenashev added on-hold This pull request depends on another event/release, and it cannot be merged right now ready-for-merge The PR is ready to go, and it will be merged soon if there is no negative feedback work-in-progress The PR is under active development, not ready to the final review and removed needs-more-reviews Complex change, which would benefit from more eyes ready-for-merge The PR is ready to go, and it will be merged soon if there is no negative feedback labels Oct 28, 2017
@oleg-nenashev oleg-nenashev self-assigned this Oct 28, 2017
@oleg-nenashev
Copy link
Member Author

Needs fix, yes. Due to whatever reason, FindBugs behaves differently in CI

@oleg-nenashev oleg-nenashev added the unresolved-merge-conflict There is a merge conflict with the target branch. label Mar 23, 2018
@oleg-nenashev
Copy link
Member Author

After #3362 this fix is not actual, but it still makes sense to revive it once we need better extensibility

Copy link
Member

@stephenc stephenc left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this still relevant?

@oleg-nenashev
Copy link
Member Author

unlikely

@batmat
Copy link
Member

batmat commented Jan 2, 2019

@oleg-nenashev also, it's conflicted. What do you think about closing it?

@batmat batmat added the proposed-for-close There is no consensus about feasibility of this PR, and maintainers do not see a way forward for it label Jan 2, 2019
@oleg-nenashev
Copy link
Member Author

Aside grumbling about priority switches and lots of almost-done work being abandoned, I am fine with that. Closing it

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
on-hold This pull request depends on another event/release, and it cannot be merged right now proposed-for-close There is no consensus about feasibility of this PR, and maintainers do not see a way forward for it unresolved-merge-conflict There is a merge conflict with the target branch. work-in-progress The PR is under active development, not ready to the final review
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants