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

How can I update the version of CFLint installed with the ColdFusion Builder extension? #327

Closed
ccsimmons opened this issue Jul 1, 2017 · 34 comments
Labels

Comments

@ccsimmons
Copy link

I looked at the post here: https://github.com/cfjedimaster/CFLint-Extension. The instructions indicate:

"To update the CFLint bits, simply download the release and copy the jars into the extension's cflint_lib folder"

I'm not sure exactly where/which jars I'm supposed to copy after I download CFLint.

I apologize if this is a stupid question.

@ryaneberly
Copy link
Contributor

Great question. I don't use CF Builder myself, and that extension hasn't been updated in a while. But you should be able replace ALL the jars in cflint_lib with the all jar from maven.

https://search.maven.org/remotecontent?filepath=com/github/cflint/CFLint/1.1.0/CFLint-1.1.0-all.jar

@ccsimmons
Copy link
Author

Thanks very much for the quick response and suggestion. I replaced all the jars with the one from above. When I run CFLint from CFBuilder I receive the attached error. If you have any suggestions that'd be great. If not I totally understand.

screen shot 2017-07-01 at 12 27 52 pm

@ryaneberly
Copy link
Contributor

Try changing line 4 of runlinter.cfm from:
linter = createObject("java","com.cflint.CFLint");
to
linter = createObject("java","com.cflint.CFLint").init(javacast('null','');

That should fix it. CFLint has grown significantly since that extension was implemented.

@TheRealAgentK
Copy link
Collaborator

@ccsimmons When you get it going, could you PR the necessary changes to Ray's project and would you mind writing up a brief setup documentation for CFBuilder / CFLint on our wiki?

@ccsimmons
Copy link
Author

@TheRealAgentK sure thing... @ryaneberly suggestion gets it running (after adding a closing parenthesis)... but I don't think it is actually finding "issues". See the attached little example where it should have returned avoid-using-cfdump-tag and avoid-using-cfabort-tag. CFLint in Atom returns them. I poked around in Ray's runlint.cfm but didn't really see anything that was obvious to me.
screen shot 2017-07-01 at 8 02 36 pm
screen shot 2017-07-01 at 8 02 53 pm

@TheRealAgentK
Copy link
Collaborator

TheRealAgentK commented Jul 2, 2017 via email

@ccsimmons
Copy link
Author

ccsimmons commented Jul 2, 2017

That's kind of what I wondered but I don't see anything obviously specifying it.

linter.scan(selection.path);
bugs = linter.getBugs();

//Do some massaging on the bugs to make it easier below
bugStruct = bugs.getBugList();
//this is a struct of issues, convert to one array
bugArr = [];

It looks like this bit above does the scan and then there is a loop over the bugStruct to append to bugArr (which is looped over to display the issues).

If I dump bugStruct it's empty.

@TheRealAgentK
Copy link
Collaborator

Hmm... I don't have CFBuilder - hard to properly test. I'll try to whip up a simple CFML page trying to run the essence of calling CFLint through CFML and see if I can reproduce it.

@TheRealAgentK
Copy link
Collaborator

TheRealAgentK commented Jul 2, 2017

@ccsimmons

In a nutshell: the issue is that there's no empty CFLint constructor anymore. You'll need to pass in a configuration object and because CF is really clunky when it comes to calling Java, it's a bit messy.

I believe something like this should work from a code point of view (at least as a starting point):

<cfscript>
    configUtils = createObject("java","com.cflint.config.ConfigUtils");   
    
    pluginInfo = createObject("java","com.cflint.config.CFLintPluginInfo");  
    pluginInfo = configUtils.loadDefaultPluginInfo();
    
    defaultConfig = createObject("java","com.cflint.config.CFLintConfig") ;
    defaultConfig.setRules(pluginInfo.getRules());
    
    myConfig = createObject("java","com.cflint.config.CFLintChainedConfig").init(defaultConfig);
    
    linter = createObject("java","com.cflint.CFLint").init(myConfig);
    WriteDump(linter);
 
    linter.scan("/Users/kai/Documents/Code/XXX/XXX/XXX/html/com");
    
    bugs = linter.getBugs();
    WriteDump(bugs);
</cfscript>

However, when I run it in my ACF 11 locally, I get an exception in my logs that point towards some logging issue/conflict:

Jul 02, 2017 1:12:12 PM org.apache.catalina.core.StandardWrapperValve invoke
SEVERE: Servlet.service() for servlet [CfmServlet] in context with path [] threw exception [Servlet execution threw an exception] with root cause
java.lang.NoClassDefFoundError: org/apache/logging/log4j/LogManager
	at net.htmlparser.jericho.LoggerProviderLog4J.getLogger(LoggerProviderLog4J.java:35)
	at net.htmlparser.jericho.LoggerProviderLog4J.getSourceLogger(LoggerProviderLog4J.java:41)
	at net.htmlparser.jericho.Source.newLogger(Source.java:1685)
	at net.htmlparser.jericho.TagType.getLogger(TagType.java:699)
	at net.htmlparser.jericho.TagType.register(TagType.java:131)
	at cfml.parsing.cfmentat.tag.CFMLTags.register(CFMLTags.java:61)
	at cfml.parsing.CFMLSource.<init>(CFMLSource.java:26)
	at com.cflint.CFLint.process(CFLint.java:242)
	at com.cflint.CFLint.scan(CFLint.java:209)
	at com.cflint.CFLint.scan(CFLint.java:198)
	at com.cflint.CFLint.scan(CFLint.java:173)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.lang.reflect.Method.invoke(Method.java:498)
	at coldfusion.runtime.StructBean.invoke(StructBean.java:508)
	at coldfusion.runtime.CfJspPage._invoke(CfJspPage.java:2553)
	at cfjenkins12ecfm437854318.runPage(/Applications/ColdFusion11/cfusion/wwwroot/jenkins1.cfm:15)
	at coldfusion.runtime.CfJspPage.invoke(CfJspPage.java:246)
	at coldfusion.tagext.lang.IncludeTag.handlePageInvoke(IncludeTag.java:736)
	at coldfusion.tagext.lang.IncludeTag.doStartTag(IncludeTag.java:572)
	at coldfusion.filter.CfincludeFilter.invoke(CfincludeFilter.java:65)
	at coldfusion.filter.IpFilter.invoke(IpFilter.java:45)
	at coldfusion.filter.ApplicationFilter.invoke(ApplicationFilter.java:487)
	at coldfusion.filter.RequestMonitorFilter.invoke(RequestMonitorFilter.java:42)
	at coldfusion.filter.MonitoringFilter.invoke(MonitoringFilter.java:40)
	at coldfusion.filter.PathFilter.invoke(PathFilter.java:142)
	at coldfusion.filter.LicenseFilter.invoke(LicenseFilter.java:30)
	at coldfusion.filter.ExceptionFilter.invoke(ExceptionFilter.java:94)
	at coldfusion.filter.ClientScopePersistenceFilter.invoke(ClientScopePersistenceFilter.java:28)
	at coldfusion.filter.BrowserFilter.invoke(BrowserFilter.java:38)
	at coldfusion.filter.NoCacheFilter.invoke(NoCacheFilter.java:58)
	at coldfusion.filter.GlobalsFilter.invoke(GlobalsFilter.java:38)
	at coldfusion.filter.DatasourceFilter.invoke(DatasourceFilter.java:22)
	at coldfusion.filter.CachingFilter.invoke(CachingFilter.java:62)
	at coldfusion.CfmServlet.service(CfmServlet.java:219)
	at coldfusion.bootstrap.BootstrapServlet.service(BootstrapServlet.java:89)
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:303)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
	at coldfusion.monitor.event.MonitoringServletFilter.doFilter(MonitoringServletFilter.java:42)
	at coldfusion.bootstrap.BootstrapFilter.doFilter(BootstrapFilter.java:46)
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:241)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
	at coldfusion.inspect.weinre.MobileDeviceDomInspectionFilter.doFilter(MobileDeviceDomInspectionFilter.java:121)
	at coldfusion.bootstrap.BootstrapFilter.doFilter(BootstrapFilter.java:46)
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:241)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
	at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:220)
	at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:122)
	at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:505)
	at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:169)
	at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:103)
	at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:116)
	at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:450)
	at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1078)
	at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:625)
	at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:316)
	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
	at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
	at java.lang.Thread.run(Thread.java:745)

@ccsimmons
Copy link
Author

Don't know if this helps... but it works if I copy the jar from the Atom plugin (.atom/packages/linter-cflint/bin/CFLint-0.10.0-all.jar) to cflint_lib instead of the one from https://search.maven.org/remotecontent?filepath=com/github/cflint/CFLint/1.1.0/CFLint-1.1.0-all.jar

screen shot 2017-07-01 at 9 18 37 pm

@ccsimmons
Copy link
Author

Sorry, I must have been writing my comment as you were posting yours.

@TheRealAgentK
Copy link
Collaborator

@ccsimmons Re the older version - I'm pretty sure that'd be the case because the way how CFLint gets executed and setup seems to have changed quite a bit between 0.10 and 1.0/1.1. See my other post re the setup - but I don't know what to do about the logging exception. That might be an issue on CF11 specifically, not sure how CFBuilder executes this and deals with library requirements.

@TheRealAgentK
Copy link
Collaborator

TheRealAgentK commented Jul 2, 2017

@ccsimmons It seems that if I put CFLint-1.1.0-all.jar in cfusion/runtime/lib instead of cfusion/lib it'll execute just fine and not throw the exception.

You will need to add bugStruct = bugs.getBugList(); to my code from above.

Also: What I've pieced together up there is just a very, very simple default config. If you want to mimic what all the configuration options can do (with .cflintrc for directories, command-line config etc) I'm pretty sure you'd need to do more than that.

It might be worthwhile to go through CFLintMain (.main() as well as .execute()) to see and understand how that's all pieced together now.

I strongly recommend you do that in the dev branch as we're releasing 1.2.0 from it very soon.

@ccsimmons
Copy link
Author

I was just about to post that I integrated what you gave me into runlint.cfm and it worked! I'm just starting to fiddle around with .cflintrc and configuration options.

screen shot 2017-07-01 at 9 36 00 pm

@TheRealAgentK
Copy link
Collaborator

If you could manage to put together something that's working and configurable based on the code I gave you, I wonder if we could put together "an entry" point into the CFLint system that can be called in an easier way from CFBuilder.

For instance com.cflint.ide.CFLintCFBuilder --- in a similar way to how there is a CFLintTask as an entry point for Ant. @ryaneberly ???

@KamasamaK
Copy link
Collaborator

Why was the no-argument constructor removed from com.cflint.CFLint? The commit message just says "clean up, decomposing the CFLint monolith a bit, remove unused methods". So I guess maybe because it was unused in this project, but that discounts external usage. I think having it as a kind of default constructor makes sense if you don't care about custom configuration.

@ccsimmons
Copy link
Author

@TheRealAgentK so would the parsing of .cflintrc need to be something done in the ColdFusion Builder extension, or would ColdFusion Builder check for the existence of .cflintrc in the project and pass the file into CFLinter for parsing (and if the file does not exist use the code above for the default settings)?

@ryaneberly
Copy link
Contributor

I think rather than CFLintCFBuilder, we just need to generically support an api, just like we support the CLI.

@TheRealAgentK
Copy link
Collaborator

@ccsimmons I'm not 100% sure how CFBuilder works - does it trigger cflint for the current file or for a path? I think in general cflintrc would be checked by CFLint and not by the extension, but I'm pretty sure that the code I've pulled together would not deal with anything else but a default config.

@TheRealAgentK
Copy link
Collaborator

@ryaneberly yes!

@ccsimmons
Copy link
Author

The CFBuilder extension checks to see if the "selection" is a file or folder but really only for the purpose of customizing the header of the resulting output to the user. It uses linter.scan(selection.path); whether the path is a folder or a file and passes either the folder path or the file's path depending on what was selected. I did also notice if you select multiple files the only one that gets scanned is the first one that was clicked.

@KamasamaK
Copy link
Collaborator

KamasamaK commented Jul 3, 2017

@ccsimmons If I'm understanding the scan method correctly, it will only load the .cflintrc if it's scanning a folder. Unfortunately, for an individual file it doesn't even check. You would be able to pass in the config to the constructor, but that too is not so simple as the loadConfig method I found, which would be ideal for creating the config object to be passed to the constructor, is private.

@TheRealAgentK
Copy link
Collaborator

How are you going with this?

@ccsimmons
Copy link
Author

Sorry for the delay. I submitted a PR to Ray a few minutes ago for an update that uses the new jar and the default configuration. What Wiki page would you like me to put the "brief setup documentation for CFBuilder / CFLint" on?

@TheRealAgentK
Copy link
Collaborator

We just talked about where to put those IDE integrations and we prefer to - in general - get people to include/host them with the respective project. The CFLint Wiki will eventually go away and all the content will be delivered via the README and associated .md files.

So, ideally a paragraph with some basic info would continue to live on our end here and ideally the instructions on how to get CFBuilder going with CFLint would live on the CFBuilder-CFLint-Extension README. Maybe you could build it into the README and PR that to Ray too?

@TheRealAgentK
Copy link
Collaborator

I see the PR was accepted by Ray - closing ticket now.

@denuno
Copy link
Collaborator

denuno commented Jul 27, 2017

Been meaning to comment on this. Unrelated to the CFB extension, the next version of the eclipse plugin for CFLint (that CFEclipse uses) can be used with CFB too. It's nice in that it has a UI for configuring rules, and eventually will have "quick fixes" that you can do to add ignores and stuff, the way you can do when editing Java.

@KamasamaK
Copy link
Collaborator

@denuno Thanks! I was going to ask about this. I installed it from here, but didn't see how it was supposed to work.

I'm very interested in this "quick fixes" too. I've seen other IDE linters have this functionality as well. I will have to check it out once you've done it to see if it can be integrated into the Atom or VS Code plugins since those platforms appear to support that.

@denuno
Copy link
Collaborator

denuno commented Jul 27, 2017

Each IDE has it's own way of doing the "quick fix" stuff (of course-- standardization is for the weak and timid!) but I'll aim to keep the implementation as agnostic as possible.

You can also do teeny Eclipse programs that only have what they need to run, which would sorta give us a GUI of sorts with what's there now, but I'd love to support more than just Eclipse, and thus make "quick fixes" and such as plug-in-able to other stuphs as possible.

@denuno
Copy link
Collaborator

denuno commented Jul 27, 2017

That would be a pretty interesting thing to have in CFLint itself, actually, along with a mode where you could enable auto-fixing (or maybe auto-ignoring)... e.g. instead of just warning about an unscoped var, optionally have it var scope it... yeah, something like enabling "suggestions", where it says what rule is broke and then also (if it is easy to figure out) shows a proposed fix.

Something to think about at least. For sure would want it to be optional, as something like that would slow things down a bit I reckon.

@KamasamaK
Copy link
Collaborator

@denuno Exactly! Perhaps you could create a new issue with your thoughts on this feature.

@ryaneberly
Copy link
Contributor

Autofix would be interesting. Some scenarios would be easier to assume the right answer than others.

@KamasamaK
Copy link
Collaborator

Sure, and perhaps in some cases you might even have more than one suggestion. Not all rules would be conducive to having that at all. But this should really have its own issue.

@ryaneberly
Copy link
Contributor

ryaneberly commented Jul 28, 2017 via email

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

5 participants