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

Add WebSphere Liberty 23.x plugin.(#10887) #560

Merged
merged 10 commits into from
Jun 25, 2023
Merged

Conversation

weixiang1862
Copy link
Member

@weixiang1862 weixiang1862 commented Jun 21, 2023

Add an agent plugin to support WebSphere Liberty

  • If this pull request closes/resolves/fixes an existing issue, replace the issue number. Closes #10887
  • Update the CHANGES log.

@wu-sheng wu-sheng added this to the 8.17.0 milestone Jun 21, 2023
@Override
public void onConstruct(final EnhancedInstance objInst, final Object[] allArguments) throws Throwable {
// add special flag for AsyncContext distinguish
objInst.setSkyWalkingDynamicField(AsyncType.COMPLETE);
Copy link
Member

Choose a reason for hiding this comment

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

This is a class level attribute. Is this class always staying in asyc completed? No race condition?

Copy link
Member Author

Choose a reason for hiding this comment

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

yes, the CompleteRunnable is created in AsyncContextImpl.complete() method with AsyncType.COMPLETE attribute and then it will be submit to an executor by AsyncContextImpl.startWithExecutorThread(). There are no race condition in the whole process, set and get this attribute is always in one thread.

Copy link
Member Author

Choose a reason for hiding this comment

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

IBM open source liberty code but not release a maven dependency(I can not find it on maven). CompleteRunnable and DispatchRunnable is not reachable in agent plugin code. That is why I use this strange way rather than xxx instanceof CompleteRunnable.

Copy link
Member

Choose a reason for hiding this comment

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

You could write classes(fake claases) in weblogic namespace and exclude them in the package stage, then, your codes could work without instanceof and have higher perf.

Copy link
Member Author

Choose a reason for hiding this comment

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

That sounds interesting, I will have a try.

Copy link
Member

Choose a reason for hiding this comment

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

Notice the license of those fake files. If you only fake some simple methods, it is fine, but ve clear that they are fake classes and not distributed in their class comments.

Copy link
Member Author

Choose a reason for hiding this comment

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

I put fake class file under org.apache.skywalking.apm.plugin.webspheresource.com.ibm.ws.webcontainer.async.

maven-jar-plugin exclude it from final jar and maven-shade-plugin relocation the packagename to com.ibm.ws.webcontainer.async.

Please help me review the code.

Copy link
Member

Choose a reason for hiding this comment

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

Please try this, list all your com.ibm.ws.webcontainer.async.*(all explicit class names) in here,

<excludes>

I hope this could work and avoid shade.

Copy link
Member Author

Choose a reason for hiding this comment

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

OK, I will try this.

@Override
public void handleMethodException(EnhancedInstance objInst, Method method, Object[] allArguments,
Class<?>[] argumentsTypes, Throwable t) {
if (ContextManager.isActive()) {
Copy link
Member

Choose a reason for hiding this comment

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

Is there a case not active? I noticed you added this check in every place. Notice that isActive has resource cost too. We only should check when it is expected to be NOT active in some specific known cases.

Copy link
Member Author

Choose a reason for hiding this comment

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

You are rignt, This check is no necessary. I will remove it.

@wu-sheng
Copy link
Member

I am a little confused, why shade?

@wu-sheng
Copy link
Member

com.ibm should be in codes, and you should exclude those(com.ibm.*) when package.
Could you explain your way?

@weixiang1862
Copy link
Member Author

I am a little confused, why shade?

Checkstyle requires sourcecode package name must start with org.apache.skywalking.apm.plugin, so i put websphere fake class under org.apache.skywalking.apm.plugin.webspheresource.com.ibm.ws.webcontainer.async.

If not shade, websphere runtime will throw java.lang.NoClassDefFoundError for org.apache.skywalking.apm.plugin.webspheresource.com.ibm.ws.webcontainer.async.CompleteRunnable.class missing

@weixiang1862
Copy link
Member Author

com.ibm should be in codes, and you should exclude those(com.ibm.*) when package. Could you explain your way?

I use maven-jar-plugin, include codes except fackclass

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-jar-plugin</artifactId>
    <configuration>
        <includes>
            <include>org/apache/skywalking/apm/plugin/websphereliberty/**/*</include>
            <include>META-INF/**/*</include>
            <include>skywalking-plugin.def</include>
        </includes>
    </configuration>
</plugin>

MethodInterceptResult result) throws Throwable {
Runnable runnable = (Runnable) allArguments[0];

if (runnable instanceof RunnableWrapper) {
Copy link
Member

Choose a reason for hiding this comment

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

About this instanceof, is this executed more than once?

Copy link
Member Author

Choose a reason for hiding this comment

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

Yes. In websphere liberty, start runnable created by AsyncContext.start() method finally will be submit to an executor by AsyncContext.startWithExecutorThread method. So enhance startWithExecutorThread is enough.

But in websphere traditional edition, start method has a check, if WSAsyncContextImpl.wcConfig.isUseAsyncRunnableWorkManager()==true, start runnable cant not enter startWithExecutorThread method. So we must enhance start method too.
image

Both enhance start & startWithExecutorThread will cause AsyncContextInterceptor run twice. So I have a instanceof RunnableWrapper check.

public ElementMatcher<MethodDescription> getMethodsMatcher() {
return named("invokeFilters")
.and(takesArgument(0, named("jakarta.servlet.ServletRequest")))
.and(takesArgument(1, named("jakarta.servlet.ServletResponse")));
Copy link
Contributor

Choose a reason for hiding this comment

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

com.ibm.ws.webcontainer.filter.WebAppFilterManager.invokeFilters have different arguments in same version websphere?

it seems javax and jakarta are in diiferent version websphere, i think it is better to develop plugins for different version websphere, you can overwrite witnessMethods to identify it

Copy link
Member Author

Choose a reason for hiding this comment

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

Yes, it is different version of websphere. WebSphere liberty use jakarta and webSphere traditional use javax.

Currnetly WebSphere Liberty 23.x plugin compatible for webSphere liberty and webSphere traditional.

You means I should create another plugin 'websphere-traditional-xx-plugin'?

Copy link
Member

Choose a reason for hiding this comment

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

I feel like javax version of codes is not tested through the scenario. @weixiang1862 Could you confirm the status?

Copy link
Member

Choose a reason for hiding this comment

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

Yes, it is different version of websphere. WebSphere liberty use jakarta and webSphere traditional use javax.

Currnetly WebSphere Liberty 23.x plugin compatible for webSphere liberty and webSphere traditional.

You means I should create another plugin 'websphere-traditional-xx-plugin'?

@weixiang1862 How do you make sure these two kinds of APIs are compiled in one plugin? Just because they have different package names? But how do you test?

I think @xu1009 's point is witness class is always recommended to do a version differentiation. Your way works too but a little tricky and implicit.
witness + 2 plugins or 2 package names should be better. Also, you should mention this on the plugin docs.

Copy link
Member Author

Choose a reason for hiding this comment

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

I feel like javax version of codes is not tested through the scenario. @weixiang1862 Could you confirm the status?

Yes,I test this case on websphere traditional 8.5.5 & 9.0.5 in my local. It is a little bit troublesome to create a websphere traditional scenario. Currently there are jvm & tomcat container for scenario test, May be I shoud create a websphere container type?

Copy link
Member

Choose a reason for hiding this comment

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

If it is EPLv2 as well, we could do that.

Copy link
Member

Choose a reason for hiding this comment

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

Notice, that(new container) should be another new PR.

Copy link
Member

Choose a reason for hiding this comment

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

@weixiang1862 For this PR, please separate traditional and jakata in two plugins with a parent module websphere-liberty

Copy link
Member Author

Choose a reason for hiding this comment

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

@wu-sheng @xu1009 OK, I will do the separate jobs these days.

By the way, Happy Dragon Boat Festival!

Copy link
Member

Choose a reason for hiding this comment

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

You too. Have a good vacation

<artifactId>maven-jar-plugin</artifactId>
<configuration>
<includes>
<include>org/apache/skywalking/apm/plugin/websphereliberty/**/*</include>
Copy link
Member

@wu-sheng wu-sheng Jun 21, 2023

Choose a reason for hiding this comment

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

Suggested change
<include>org/apache/skywalking/apm/plugin/websphereliberty/**/*</include>
<include>org/apache/skywalking/apm/plugin/websphereliberty/v23/**</include>

And move the fake classes into org/apache/skywalking/apm/plugin/websphereliberty/mock.

@weixiang1862
Copy link
Member Author

@wu-sheng @xu1009 I made the following changes in this commit:

  1. move mock class to com.ibm.** package and add them to check-style exclude list
  2. use com.ibm.ws.webcontainer.WebContainer.handleRequest(IRequest, IResponse) as interceptor point, it is high level class and hided the detail of real implement(javax or jakarta). So the plugin still keep one.

@wu-sheng
Copy link
Member

move mock class to com.ibm.** package and add them to check-style exclude list

I can't find it in the change log. There are the changes?

@weixiang1862
Copy link
Member Author

move mock class to com.ibm.** package and add them to check-style exclude list

I can't find it in the change log. There are the changes?

Yes, mock classes are currently in com.ibm.** packages and I add these mock classes to maven-checkstyle-plugin exclude list

image

pom.xml Show resolved Hide resolved
@wu-sheng wu-sheng requested a review from xu1009 June 25, 2023 06:21
Copy link
Member

@wu-sheng wu-sheng left a comment

Choose a reason for hiding this comment

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

LGTM. Pending on @xu1009 recheck.

@wu-sheng wu-sheng merged commit e464f18 into apache:main Jun 25, 2023
158 of 174 checks passed
yangyulely pushed a commit to yangyulely/skywalking-java that referenced this pull request May 25, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants