Custom Java syntax checker/linter woes

I’m having trouble getting a custom Java linter I wrote back in 2012 (following http://komodoide.com/blog/2012-02/diving-deep-komodos-syntax-checker/ and //docs.activestate.com/komodo/8.5/linter-reference.html) to work with Komodo 8.5. I’ve tried to make my class as similar as possbile to existing built-in linters, such as http://svn.openkomodo.com/openkomodo/view/openkomodo/trunk/src/lint/koPHPLinter.py, but I’m still getting errors:

[2014-04-16 12:35:10,572] [ERROR] lint: 
-- EXCEPTION START --
[Exception... "Component returned failure code: 0x8000ffff (NS_ERROR_UNEXPECTED) [koILintService.addRequest]"  nsresult: "0x8000ffff (NS_ERROR_UNEXPECTED)"  location: "JS frame :: chrome://komodo/content/lint/lint.js :: <TOP_LEVEL> :: line 432"  data: no]
+ message (string) 'Component returned failure code: 0x8000ffff (NS_ERROR_UNEXPECTED) [koILintService.addRequest]'
+ QueryInterface (function) 3 lines
+ result (number) 2147549183
+ name (string) 'NS_ERROR_UNEXPECTED'
+ filename (string) 'chrome://komodo/content/lint/lint.js'
+ lineNumber (number) 432
+ columnNumber (number) 0
+ location (object) JS frame :: chrome://komodo/content/lint/lint.js :: <TOP_LEVEL> :: line 432
| + QueryInterface (function) 3 lines
| + language (number) 2
| + languageName (string) 'JavaScript'
| + filename (string) 'chrome://komodo/content/lint/lint.js'
| + name (object) null
| + lineNumber (number) 432
| + sourceLine (object) null
| + caller (object) JS frame :: chrome://komodo/content/lint/lint.js :: <TOP_LEVEL> :: line 376
| + inner (object) null
| + data (object) null
| + initialize (function) 3 lines
-- EXCEPTION END --

I’m not sure what I’m doing wrong here. All that my linter does is call a shell-script with the temporary file I write out. Bizarrely, though, even when I change it so that lint_with_text does nothing but return a dummy koLintResults with a single dummy KoLintResult, I get the same error.

My main koJavaLinter.py file reads as follows:

#!python
# Copyright (c) 2012-2014 Barry van Oudtshoorn

"""koJavaLinter - syntax-check Java code with CheckStyle """

from xpcom import componenets, nsError, COMException
from koLintResult import *
from koLintResults import koLintResults
import os, sys, re, which
import logging
import tempfile
import string
import process
import koprocessutils

import projectUtils

log = logging.getLogger('koJavaLinter')
log.setLevel(logging.DEBUG)

class koJavaLinter:
    _com_interfaces_ = [components.interfaces.koILinter]
    _reg_desc_ = "Java Linter"
    _reg_clsid_ = "{ba29477c-7db6-465b-9b4c-cef0edb77372}"
    _reg_contractid_ = "@activestate.com/koLinter?language=Java;1"
    _reg_categories_ = [
        ("category-komodo-linter", 'Java&type=com.seqta:CheckStyle'),
        ]

    def lint(self, request):
        encoding_name = request.encoding.python_encoding_name
        text = request.content.encode(encoding_name)
        return self.lint_with_text(request, text)
    
    def lint_with_text(self, request, text):
        if not text:
            return None
        cwd = request.cwd
        
        javaTemp = tempfile.mktemp()
        fout = open(javaTemp, 'wb')
        fout.write(text)
        fout.close()
        
        p = None
        # We only need the stderr result.
        try:
            argv = ["checkstyle.sh", javaTemp]
            env = koprocessutils.getUserEnv()
            cwd = cwd or None
            p = process.ProcessOpen(argv, cwd=cwd, env=env)
            stdout, stderr = p.communicate()
            #log.debug("checkstyle run: stdout:%s, stderr:%s", stdout, stderr)
            lines = stderr.splitlines(1)
        finally:
            os.unlink(javaTemp)
        
        ptn = re.compile(r'^(?:.*?)\:(\d+)(?:\:*?)(\d)*?\:\s(.*)$')
        results = koLintResults()
        if lines:
            for line in lines:
                m = ptn.match(line)
                if m:
                    try:
                        lineNo = int(m.group(1))
                    except ValueError, e:
                        continue
                    try:
                        colNo = int(m.group(2))
                    except ValueError, e:
                        continue
                    
                    result = KoLintResult()
                    result.description = m.group(3)
                    result.lineStart = result.lineEnd = lineNo
                    result.columnStart = colNo
                    result.columnEnd = colNo + 200 # yuk
                    result.severity = result.SEV_ERROR
                    results.addResult(result)
        
        return results

Oddly, this did work a few years ago, so I’m guessing that something has changed in Komodo in the mean time…? Any help on getting this working would be great!

It would help if you added some logging code to koLintService.py, restart Komodo, and check the logs:

    Index: koLintService.py
    =======================================
    --- koLintService.py    (revision 85499)
    +++ koLintService.py    (working copy)
    @@ -564,7 +564,11 @@
                             log.debug("manager thread: call linter.lint(request)")
                             try:
                                 if request.alwaysLint or self._passesGenericCheck(request):
    -                                results = request.linter.lint(request)
    +                                try:
    +                                    results = request.linter.lint(request)
    +                                except:
    +                                    log.exception("Linting failed")
    +                                    raise
                                     #results = UnwrapObject(request.linter).lint(request)
                                     # This makes a red statusbar icon go green, but it
                                     # might not be what we always want.

  • Eric

Thanks for the quick response, @ericp.

[2014-04-17 09:30:39,249] [ERROR] lint: 
-- EXCEPTION START --
[Exception... "Component returned failure code: 0x8000ffff (NS_ERROR_UNEXPECTED) [koILintService.addRequest]"  nsresult: "0x8000ffff (NS_ERROR_UNEXPECTED)"  location: "JS frame :: chrome://komodo/content/lint/lint.js :: <TOP_LEVEL> :: line 432"  data: no]
+ message (string) 'Component returned failure code: 0x8000ffff (NS_ERROR_UNEXPECTED) [koILintService.addRequest]'
+ QueryInterface (function) 3 lines
+ result (number) 2147549183
+ name (string) 'NS_ERROR_UNEXPECTED'
+ filename (string) 'chrome://komodo/content/lint/lint.js'
+ lineNumber (number) 432
+ columnNumber (number) 0
+ location (object) JS frame :: chrome://komodo/content/lint/lint.js :: <TOP_LEVEL> :: line 432
| + QueryInterface (function) 3 lines
| + language (number) 2
| + languageName (string) 'JavaScript'
| + filename (string) 'chrome://komodo/content/lint/lint.js'
| + name (object) null
| + lineNumber (number) 432
| + sourceLine (object) null
| + caller (object) JS frame :: chrome://komodo/content/lint/lint.js :: lint_doRequest :: line 658
| + inner (object) null
| + data (object) null
| + initialize (function) 3 lines
-- EXCEPTION END --

If I change the loglevel to debug, I get a little bit more info – but basically it just seems to be saying that it’s received the lint request. :confused:

[2014-04-17 09:32:53,341] [INFO] koLintService: KoLintService.addRequest(<KoLintRequest: Java on uid {96795f05-ca0e-4bd8-8650-df52a7983688}>)
[2014-04-17 09:32:53,343] [ERROR] lint: 
-- EXCEPTION START --
[Exception... "Component returned failure code: 0x8000ffff (NS_ERROR_UNEXPECTED) [koILintService.addRequest]"  nsresult: "0x8000ffff (NS_ERROR_UNEXPECTED)"  location: "JS frame :: chrome://komodo/content/lint/lint.js :: <TOP_LEVEL> :: line 432"  data: no]
+ message (string) 'Component returned failure code: 0x8000ffff (NS_ERROR_UNEXPECTED) [koILintService.addRequest]'
+ QueryInterface (function) 3 lines
+ result (number) 2147549183
+ name (string) 'NS_ERROR_UNEXPECTED'
+ filename (string) 'chrome://komodo/content/lint/lint.js'
+ lineNumber (number) 432
+ columnNumber (number) 0
+ location (object) JS frame :: chrome://komodo/content/lint/lint.js :: <TOP_LEVEL> :: line 432
| + QueryInterface (function) 3 lines
| + language (number) 2
| + languageName (string) 'JavaScript'
| + filename (string) 'chrome://komodo/content/lint/lint.js'
| + name (object) null
| + lineNumber (number) 432
| + sourceLine (object) null
| + caller (object) JS frame :: chrome://komodo/content/lint/lint.js :: lint_doRequest :: line 658
| + inner (object) null
| + data (object) null
| + initialize (function) 3 lines
-- EXCEPTION END --

Some investigation suggests that the error is raised in _getLinterByCID – in particular, the line linter = components.classes[linterCID].createInstance(components.interfaces.koILinter). Unfortunately, that’s probably about the extent of what I can determine without knowing more about how everything fits together behind the scenes in Komodo. Does this perhaps spark any ideas as to what might be going on?

I’ve tried to do a bit more digging, but unfortunately I’ve not been able to get any further, really. I think that this is an issue in Komodo somewhere, rather than in my code, but I’d be really happy to be proven wrong… :slight_smile: