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

Wikimedia Commons extension doesn't appear in 3.8.0 #6581

Open
trnstlntk opened this issue May 1, 2024 · 16 comments
Open

Wikimedia Commons extension doesn't appear in 3.8.0 #6581

trnstlntk opened this issue May 1, 2024 · 16 comments
Labels
Status: Pending Review Indicates that the issue or pull request is awaiting review by project maintainers or collaborators Type: Bug Issues related to software defects or unexpected behavior, which require resolution.

Comments

@trnstlntk
Copy link
Contributor

Folks who upgraded to 3.8.0 have lost the Wikimedia Commons extension. It's also gone on Wikimedia PAWS.

I have tried uninstalling and reinstalling the extension and it still doesn't appear.

@trnstlntk trnstlntk added Status: Pending Review Indicates that the issue or pull request is awaiting review by project maintainers or collaborators Type: Bug Issues related to software defects or unexpected behavior, which require resolution. labels May 1, 2024
@vivian-rook
Copy link

I believe the same issue is seen in https://phabricator.wikimedia.org/T363917 I've rolled back to 3.7.9 in PAWS and the issue resolved.

@wetneb
Copy link
Sponsor Member

wetneb commented May 13, 2024

@sebastian-berlin-wmse @lokal-profil how does this issue fit within your development plans? Do you intend to work on it or do you see this as low priority (or out of scope)?

If any fix is required on OpenRefine's side I would be keen to include it in a 3.8.1 release, which should ideally come out soon given that we have other important fixes to release (see #6599).

If you don't intend to work on this soon I would try to find other ways to fix it (such as doing it myself).

@sebastian-berlin-wmse
Copy link

I'll have a look.

@sebastian-berlin-wmse
Copy link

For me, the extension only shows up in 3.7.7 and no later version (tried 3.7.8, 3.7.9 and 3.8.0). @wetneb, can you point me in the direction of where extensions are loaded so I can debug? I looked around a bit in the documentation and in the code, but I haven't found a good starting point.

@wetneb
Copy link
Sponsor Member

wetneb commented May 15, 2024

On the frontend side, extensions are loaded by including whatever Javascript files they declare into the page (project-bundle.js or index-bundle.js). On the backend side, the Jar files they include are loaded and the server-side components are registered (via the controller.js file).

To debug the frontend you could look at the developer console to see if any errors appear there, or put breakpoints on the extension JS code to see if/how it gets executed.

To debug the backend code you could first look at the server logs to see if any errors appear there. Running OpenRefine to debug an extension in Java is more involved (I am not sure how to set it up) but I generally work by writing unit tests which reproduce the bug and then debug the code via the IDE when running those tests.

We can also look at this together in our call on Thursday.

@sebastian-berlin-wmse
Copy link

Turns out that my issue was because I misunderstood the instructions for installing extensions. I put commons-extension/ in extensions/ in OpenRefine root rather than in webapp/extensions/. I think I was confused by the screenshot under Install this extension in OpenRefine, which I now realise is of the workspace directory. Now the source for Commons shows up in 3.7.9, but not 3.8.0.

@sebastian-berlin-wmse
Copy link

I've managed to track down that 0945595 is the revision Commons stops showing up in the list of sources. It's a small change that only updates the Velocity library.

@wetneb
Copy link
Sponsor Member

wetneb commented May 23, 2024

When loading the Commons extension just after this commit, I get:

2024-05-23T07:09:17.797150029Z pool-2-thread-7 ERROR An exception occurred processing Appender LogToConsole org.apache.logging.log4j.core.appender.AppenderLoggingException: java.lang.NoClassDefFoundError: org/apache/commons/lang3/exception/ExceptionUtils
	at org.apache.logging.log4j.core.config.AppenderControl.tryCallAppender(AppenderControl.java:164)
	at org.apache.logging.log4j.core.config.AppenderControl.callAppender0(AppenderControl.java:133)
	at org.apache.logging.log4j.core.config.AppenderControl.callAppenderPreventRecursion(AppenderControl.java:124)
	at org.apache.logging.log4j.core.config.AppenderControl.callAppender(AppenderControl.java:88)
	at org.apache.logging.log4j.core.config.LoggerConfig.callAppenders(LoggerConfig.java:705)
	at org.apache.logging.log4j.core.config.LoggerConfig.processLogEvent(LoggerConfig.java:663)
	at org.apache.logging.log4j.core.config.LoggerConfig.log(LoggerConfig.java:639)
	at org.apache.logging.log4j.core.config.LoggerConfig.logParent(LoggerConfig.java:696)
	at org.apache.logging.log4j.core.config.LoggerConfig.processLogEvent(LoggerConfig.java:665)
	at org.apache.logging.log4j.core.config.LoggerConfig.log(LoggerConfig.java:639)
	at org.apache.logging.log4j.core.config.LoggerConfig.log(LoggerConfig.java:540)
	at org.apache.logging.log4j.core.config.AwaitCompletionReliabilityStrategy.log(AwaitCompletionReliabilityStrategy.java:67)
	at org.apache.logging.log4j.core.Logger.logMessage(Logger.java:155)
	at org.apache.log4j.Category.maybeLog(Category.java:560)
	at org.apache.log4j.Category.error(Category.java:291)
	at org.apache.velocity.runtime.log.Log4JLogChute.log(Log4JLogChute.java:197)
	at org.apache.velocity.runtime.log.LogDisplayWrapper.log(LogDisplayWrapper.java:94)
	at org.apache.velocity.runtime.log.LogDisplayWrapper.error(LogDisplayWrapper.java:200)
	at org.apache.velocity.runtime.VelocimacroFactory.initVelocimacro(VelocimacroFactory.java:218)
	at org.apache.velocity.runtime.RuntimeInstance.init(RuntimeInstance.java:261)
	at org.apache.velocity.runtime.RuntimeInstance.init(RuntimeInstance.java:589)
	at org.apache.velocity.app.VelocityEngine.init(VelocityEngine.java:135)
	at edu.mit.simile.butterfly.Butterfly.configureModules(Butterfly.java:862)
	at edu.mit.simile.butterfly.Butterfly.configure(Butterfly.java:428)
	at edu.mit.simile.butterfly.Butterfly.init(Butterfly.java:295)
	at org.eclipse.jetty.servlet.ServletHolder$Wrapper.init(ServletHolder.java:1305)
	at org.eclipse.jetty.servlet.ServletHolder.initServlet(ServletHolder.java:633)
	at org.eclipse.jetty.servlet.ServletHolder.getServlet(ServletHolder.java:486)
	at org.eclipse.jetty.servlet.ServletHolder.prepare(ServletHolder.java:731)
	at org.eclipse.jetty.servlet.ServletHandler.doHandle(ServletHandler.java:524)
	at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:131)
	at org.eclipse.jetty.security.SecurityHandler.handle(SecurityHandler.java:578)
	at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:122)
	at org.eclipse.jetty.server.handler.ScopedHandler.nextHandle(ScopedHandler.java:223)
	at org.eclipse.jetty.server.session.SessionHandler.doHandle(SessionHandler.java:1570)
	at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:131)
	at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:122)
	at org.eclipse.jetty.server.handler.gzip.GzipHandler.handle(GzipHandler.java:822)
	at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:122)
	at org.eclipse.jetty.server.handler.ScopedHandler.nextHandle(ScopedHandler.java:223)
	at org.eclipse.jetty.server.handler.ContextHandler.doHandle(ContextHandler.java:1384)
	at org.eclipse.jetty.server.handler.ScopedHandler.nextScope(ScopedHandler.java:176)
	at org.eclipse.jetty.servlet.ServletHandler.doScope(ServletHandler.java:484)
	at org.eclipse.jetty.server.session.SessionHandler.doScope(SessionHandler.java:1543)
	at org.eclipse.jetty.server.handler.ScopedHandler.nextScope(ScopedHandler.java:174)
	at org.eclipse.jetty.server.handler.ContextHandler.doScope(ContextHandler.java:1306)
	at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:129)
	at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:122)
	at com.google.refine.ValidateHostHandler.handle(ValidateHostHandler.java:93)
	at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:122)
	at org.eclipse.jetty.server.Server.handle(Server.java:563)
	at org.eclipse.jetty.server.HttpChannel$RequestDispatchable.dispatch(HttpChannel.java:1598)
	at org.eclipse.jetty.server.HttpChannel.dispatch(HttpChannel.java:753)
	at org.eclipse.jetty.server.HttpChannel.handle(HttpChannel.java:501)
	at org.eclipse.jetty.server.HttpConnection.onFillable(HttpConnection.java:282)
	at org.eclipse.jetty.io.AbstractConnection$ReadCallback.succeeded(AbstractConnection.java:314)
	at org.eclipse.jetty.io.FillInterest.fillable(FillInterest.java:100)
	at org.eclipse.jetty.io.SelectableChannelEndPoint$1.run(SelectableChannelEndPoint.java:53)
	at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1136)
	at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:635)
	at java.base/java.lang.Thread.run(Thread.java:840)
Caused by: java.lang.NoClassDefFoundError: org/apache/commons/lang3/exception/ExceptionUtils
	at com.google.util.logging.IndentingLayout.toSerializable(IndentingLayout.java:137)
	at com.google.util.logging.IndentingLayout.toSerializable(IndentingLayout.java:54)
	at org.apache.logging.log4j.core.layout.AbstractStringLayout.toByteArray(AbstractStringLayout.java:295)
	at org.apache.logging.log4j.core.layout.AbstractLayout.encode(AbstractLayout.java:207)
	at org.apache.logging.log4j.core.layout.AbstractLayout.encode(AbstractLayout.java:36)
	at org.apache.logging.log4j.core.appender.AbstractOutputStreamAppender.directEncodeEvent(AbstractOutputStreamAppender.java:227)
	at org.apache.logging.log4j.core.appender.AbstractOutputStreamAppender.tryAppend(AbstractOutputStreamAppender.java:220)
	at org.apache.logging.log4j.core.appender.AbstractOutputStreamAppender.append(AbstractOutputStreamAppender.java:211)
	at org.apache.logging.log4j.core.config.AppenderControl.tryCallAppender(AppenderControl.java:160)
	... 60 more
Caused by: java.lang.ClassNotFoundException: org.apache.commons.lang3.exception.ExceptionUtils
	at java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:641)
	at java.base/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(ClassLoaders.java:188)
	at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:525)
	... 69 more

@wetneb
Copy link
Sponsor Member

wetneb commented May 23, 2024

So after a joint investigation in our weekly call with @sebastian-berlin-wmse, we found out that the problem is coming from the presence of two incompatible copies of the velocity library in the classpath, following #6190.

While #6190 updated velocity in OpenRefine, it did not update velocity in Butterfly, meaning that we ship both org.apache.velocity:velocity:jar:1.6.3 and org.apache.velocity:velocity-engine-core:jar:2.3 in our classpath.

The upgrade was motivated by a vulnerability in velocity, which does not actually have implications for OpenRefine since our velocity templates are not user-controlled, so I would be tempted to first release a 3.8.2 with this PR reverted, and then work on upgrading velocity in Butterfly and shipping this upgrade in a later version.

@wetneb
Copy link
Sponsor Member

wetneb commented May 23, 2024

I actually do not understand why Velocity should be a dependency of OpenRefine itself. I think it should intuitively be a dependency of Butterfly only, because I can't recall anywhere where we use it in OpenRefine. I have tried removing the dependency in OpenRefine and OR seems to still work fine without (I haven't tried running the Cypress test suite though).

However, reverting #6190 (be it by downgrading velocity or removing it entirely) does not seem to make the Commons extension work again.

Although it would still be interesting to understand the cause of the incompatibility, I think it would also be worth updating the version of OpenRefine that the Commons extension is built against:
https://github.com/OpenRefine/CommonsExtension/blob/f0fb6694d08b7a81c83b249c43a11024b0186b70/pom.xml#L23
and releasing a new version of the Commons extension. That would likely help.

@tfmorris
Copy link
Member

This is why we need better isolation for extension dependencies. I'll try to have a look at what's going on sometime over the long weekend.

@sebastian-berlin-wmse
Copy link

I tried changing the version of OR for the extension to 3.8.1 and it doesn't compile:

$ mvn compile
[INFO] Scanning for projects...
[INFO] 
[INFO] ---------< org.openrefine.extensions:refine-commons-extension >---------
[INFO] Building OpenRefine - Commons extension 0.1.2-SNAPSHOT
[INFO] --------------------------------[ jar ]---------------------------------
[INFO] 
[INFO] --- maven-resources-plugin:3.2.0:resources (default-resources) @ refine-commons-extension ---
[INFO] Using 'UTF-8' encoding to copy filtered resources.
[INFO] Using 'UTF-8' encoding to copy filtered properties files.
[INFO] skip non existing resourceDirectory /home/sebastian/workspace/open-refine/CommonsExtension/src/main/resources
[INFO] 
[INFO] --- maven-compiler-plugin:3.8.1:compile (default-compile) @ refine-commons-extension ---
[INFO] Changes detected - recompiling the module!
[INFO] Compiling 10 source files to /home/sebastian/workspace/open-refine/CommonsExtension/module/MOD-INF/classes
[INFO] Some messages have been simplified; recompile with -Xdiags:verbose to get full output
[INFO] -------------------------------------------------------------
[ERROR] COMPILATION ERROR : 
[INFO] -------------------------------------------------------------
[ERROR] /home/sebastian/workspace/open-refine/CommonsExtension/src/main/java/org/openrefine/extensions/commons/importer/CommonsImporter.java:[100,35] no suitable constructor found for StandardReconConfig(java.lang.String,java.lang.String,java.lang.String,java.lang.String,java.lang.String,boolean,java.util.ArrayList<com.google.refine.model.recon.StandardReconConfig.ColumnDetail>,int)
    constructor com.google.refine.model.recon.StandardReconConfig.StandardReconConfig(java.lang.String,java.lang.String,java.lang.String,com.google.refine.model.ReconType,boolean,int,java.util.List<com.google.refine.model.recon.StandardReconConfig.ColumnDetail>,int) is not applicable
      (argument mismatch; java.lang.String cannot be converted to com.google.refine.model.ReconType)
    constructor com.google.refine.model.recon.StandardReconConfig.StandardReconConfig(java.lang.String,java.lang.String,java.lang.String,java.lang.String,java.lang.String,boolean,int,java.util.List<com.google.refine.model.recon.StandardReconConfig.ColumnDetail>) is not applicable
      (argument mismatch; java.util.ArrayList<com.google.refine.model.recon.StandardReconConfig.ColumnDetail> cannot be converted to int)
[ERROR] /home/sebastian/workspace/open-refine/CommonsExtension/src/main/java/org/openrefine/extensions/commons/importer/FileRecordToRows.java:[44,28] no suitable constructor found for StandardReconConfig(java.lang.String,java.lang.String,java.lang.String,<nulltype>,<nulltype>,boolean,java.util.List<java.lang.Object>)
    constructor com.google.refine.model.recon.StandardReconConfig.StandardReconConfig(java.lang.String,java.lang.String,java.lang.String,com.google.refine.model.ReconType,boolean,int,java.util.List<com.google.refine.model.recon.StandardReconConfig.ColumnDetail>,int) is not applicable
      (actual and formal argument lists differ in length)
    constructor com.google.refine.model.recon.StandardReconConfig.StandardReconConfig(java.lang.String,java.lang.String,java.lang.String,java.lang.String,java.lang.String,boolean,int,java.util.List<com.google.refine.model.recon.StandardReconConfig.ColumnDetail>) is not applicable
      (actual and formal argument lists differ in length)
    constructor com.google.refine.model.recon.StandardReconConfig.StandardReconConfig(java.lang.String,java.lang.String,java.lang.String,java.lang.String,java.lang.String,boolean,int,java.util.List<com.google.refine.model.recon.StandardReconConfig.ColumnDetail>,int) is not applicable
      (actual and formal argument lists differ in length)
[INFO] 2 errors 
[INFO] -------------------------------------------------------------
[INFO] ------------------------------------------------------------------------
[INFO] BUILD FAILURE
[INFO] ------------------------------------------------------------------------
[INFO] Total time:  3.546 s
[INFO] Finished at: 2024-05-30T09:47:10+02:00
[INFO] ------------------------------------------------------------------------
[ERROR] Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:3.8.1:compile (default-compile) on project refine-commons-extension: Compilation failure: Compilation failure: 
[ERROR] /home/sebastian/workspace/open-refine/CommonsExtension/src/main/java/org/openrefine/extensions/commons/importer/CommonsImporter.java:[100,35] no suitable constructor found for StandardReconConfig(java.lang.String,java.lang.String,java.lang.String,java.lang.String,java.lang.String,boolean,java.util.ArrayList<com.google.refine.model.recon.StandardReconConfig.ColumnDetail>,int)
[ERROR]     constructor com.google.refine.model.recon.StandardReconConfig.StandardReconConfig(java.lang.String,java.lang.String,java.lang.String,com.google.refine.model.ReconType,boolean,int,java.util.List<com.google.refine.model.recon.StandardReconConfig.ColumnDetail>,int) is not applicable
[ERROR]       (argument mismatch; java.lang.String cannot be converted to com.google.refine.model.ReconType)
[ERROR]     constructor com.google.refine.model.recon.StandardReconConfig.StandardReconConfig(java.lang.String,java.lang.String,java.lang.String,java.lang.String,java.lang.String,boolean,int,java.util.List<com.google.refine.model.recon.StandardReconConfig.ColumnDetail>) is not applicable
[ERROR]       (argument mismatch; java.util.ArrayList<com.google.refine.model.recon.StandardReconConfig.ColumnDetail> cannot be converted to int)
[ERROR] /home/sebastian/workspace/open-refine/CommonsExtension/src/main/java/org/openrefine/extensions/commons/importer/FileRecordToRows.java:[44,28] no suitable constructor found for StandardReconConfig(java.lang.String,java.lang.String,java.lang.String,<nulltype>,<nulltype>,boolean,java.util.List<java.lang.Object>)
[ERROR]     constructor com.google.refine.model.recon.StandardReconConfig.StandardReconConfig(java.lang.String,java.lang.String,java.lang.String,com.google.refine.model.ReconType,boolean,int,java.util.List<com.google.refine.model.recon.StandardReconConfig.ColumnDetail>,int) is not applicable
[ERROR]       (actual and formal argument lists differ in length)
[ERROR]     constructor com.google.refine.model.recon.StandardReconConfig.StandardReconConfig(java.lang.String,java.lang.String,java.lang.String,java.lang.String,java.lang.String,boolean,int,java.util.List<com.google.refine.model.recon.StandardReconConfig.ColumnDetail>) is not applicable
[ERROR]       (actual and formal argument lists differ in length)
[ERROR]     constructor com.google.refine.model.recon.StandardReconConfig.StandardReconConfig(java.lang.String,java.lang.String,java.lang.String,java.lang.String,java.lang.String,boolean,int,java.util.List<com.google.refine.model.recon.StandardReconConfig.ColumnDetail>,int) is not applicable
[ERROR]       (actual and formal argument lists differ in length)
[ERROR] -> [Help 1]
[ERROR] 
[ERROR] To see the full stack trace of the errors, re-run Maven with the -e switch.
[ERROR] Re-run Maven using the -X switch to enable full debug logging.
[ERROR] 
[ERROR] For more information about the errors and possible solutions, please read the following articles:
[ERROR] [Help 1] http://cwiki.apache.org/confluence/display/MAVEN/MojoFailureException

@sebastian-berlin-wmse
Copy link

I fixed the compile errors above using the suggestions provided by my IDE. Unfortunately, after that worked I got the same error as in #6581 (comment).

@tfmorris
Copy link
Member

I've managed to track down that 0945595 is the revision Commons stops showing up in the list of sources. It's a small change that only updates the Velocity library.

Although it "only" updates Velocity, it's a major upgrade from 1.5 to 2.3. Apparently the error handling has changed. I'm still investigating to see exactly how it changed and how we need to compensate for it.

@tfmorris
Copy link
Member

I suspect the error in #6581 (comment) is caused by stale .class files.

The change in resource loading behavior actually happened between Velocity 1.5, which is a dependency of OpenRefine 3.7.7, and Velocity 1.6.3 which is what the version of Butterfly was bundling at that point. I thought perhaps we could just depend on the Butterfly version, but it has the problem as well. We would need to revert to Velocity 1.5 to fix the immediate problem (or tell extension writers to check their extensions for this problem).

Longer term (i.e. post 3.8.*) we probably want to have OpenRefine use Butterfly's version of Velocity so that we only have a single version.

@tfmorris
Copy link
Member

The compilation errors in #6581 (comment) are worrying because they seem to indicate incompatible API changes. That deserves more investigation.

Similarly, I came across #6375 while debugging and we should be sure to warn extension developers about those removed dependencies in case they have undeclared dependencies on them.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Status: Pending Review Indicates that the issue or pull request is awaiting review by project maintainers or collaborators Type: Bug Issues related to software defects or unexpected behavior, which require resolution.
Projects
None yet
Development

No branches or pull requests

5 participants