groovy
  1. groovy
  2. GROOVY-4020

java.lang.ClassFormatError when using the name including "-" sign

    Details

    • Type: Bug Bug
    • Status: Open Open
    • Priority: Major Major
    • Resolution: Unresolved
    • Affects Version/s: 1.6.5
    • Fix Version/s: None
    • Component/s: Compiler
    • Labels:
      None
    • Number of attachments :
      0

      Description

      I'm not sure if there any constraint with the name parameter before passing to GroovyCodeSource but it is raising an exception if the name includes "-" sign :

      GroovyCodeSource gcs = new GroovyCodeSource(inputStream, "file-name.gtmpl", "/groovy/shell");

      Here is the exception :

      Caused by: java.lang.ClassFormatError: Illegal class name "File-name" in class file File-name
      at java.lang.ClassLoader.defineClass1(Native Method)
      at java.lang.ClassLoader.defineClass(ClassLoader.java:616)
      at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:124)
      at groovy.lang.GroovyClassLoader.access$200(GroovyClassLoader.java:54)
      at groovy.lang.GroovyClassLoader$ClassCollector.createClass(GroovyClassLoader.java:482)
      at groovy.lang.GroovyClassLoader$ClassCollector.onClassNode(GroovyClassLoader.java:499)
      at groovy.lang.GroovyClassLoader$ClassCollector.call(GroovyClassLoader.java:503)
      at org.codehaus.groovy.control.CompilationUnit$10.call(CompilationUnit.java:728)
      at org.codehaus.groovy.control.CompilationUnit.applyToPrimaryClassNodes(CompilationUnit.java:925)
      at org.codehaus.groovy.control.CompilationUnit.compile(CompilationUnit.java:462)
      at groovy.lang.GroovyClassLoader.parseClass(GroovyClassLoader.java:278)

      It seems that the name parameter is used for createing Class in Java, so it must be a binary name as defined by the Java Language Specification. If so, the name would be validated and converted to good one ? Or I must to take care of that myself before using GroovyCodeSource ?

        Activity

        Hide
        Roshan Dawrani added a comment -

        Not really.

        GROOVY-3054 seems more about extracting just the file name part from the whole path of the script file. So, if you have c:/groovy/MyScript.groovy, it removes "c:/groovy/" from the front and ".groovy" from the end and comes up with MyScript as the class name. It, kind-of, assumes that file name portion itself will be a valid one, and not like "file-name.gtmpl" - that is the portion that needs to be fixed now.

        Show
        Roshan Dawrani added a comment - Not really. GROOVY-3054 seems more about extracting just the file name part from the whole path of the script file. So, if you have c:/groovy/MyScript.groovy, it removes "c:/groovy/" from the front and ".groovy" from the end and comes up with MyScript as the class name. It, kind-of, assumes that file name portion itself will be a valid one, and not like "file-name.gtmpl" - that is the portion that needs to be fixed now.
        Hide
        Nicolas RAOUL added a comment -

        I can confirm this on Ubuntu 2011.04 with bash and Groovy 1.7.4 JVM: 1.6.0_22:

        $ groovy xmlslurper-url-bug.groovy
        Caught: java.lang.ClassFormatError: Illegal class name "xmlslurper-url-bug" in class file xmlslurper-url-bug
        $ mv xmlslurper-url-bug.groovy xmlslurperurlbug.groovy
        $ groovy xmlslurperurlbug.groovy
        Hello World

        Show
        Nicolas RAOUL added a comment - I can confirm this on Ubuntu 2011.04 with bash and Groovy 1.7.4 JVM: 1.6.0_22: $ groovy xmlslurper-url-bug.groovy Caught: java.lang.ClassFormatError: Illegal class name "xmlslurper-url-bug" in class file xmlslurper-url-bug $ mv xmlslurper-url-bug.groovy xmlslurperurlbug.groovy $ groovy xmlslurperurlbug.groovy Hello World
        Hide
        Aaron J. Garcia added a comment -

        I'm having this exact same issue. I'm trying to make a Groovy CGI Script, and I want to call it "test-groovy.cgi". I have to do one of two things:

        1) Make a class definition inside of test-groovy.cgi with a good name like TestGroovy, and a main method.
        2) Rename my file to testGroovy.cgi.

        I think a good solution would be to just remove the "-" from the file name when creating the generated class name.

        Show
        Aaron J. Garcia added a comment - I'm having this exact same issue. I'm trying to make a Groovy CGI Script, and I want to call it "test-groovy.cgi". I have to do one of two things: 1) Make a class definition inside of test-groovy.cgi with a good name like TestGroovy, and a main method. 2) Rename my file to testGroovy.cgi. I think a good solution would be to just remove the "-" from the file name when creating the generated class name.
        Hide
        Paul King added a comment -

        I think Roshan's suggestion of reusing org.codehaus.groovy.bsf.GroovyEngine#convertToValidJavaClassname() is the way to go. This would not remove characters like '-' but instead replace them with '_'. Which would be a potential problem for scripts which somehow already had such a class with an underscore - but such systems would already break under BSF anyway. Any objections?

        I also think the method should be moved into some util class outside of BSF and then called from BSF and wherever else it is needed.

        Show
        Paul King added a comment - I think Roshan's suggestion of reusing org.codehaus.groovy.bsf.GroovyEngine#convertToValidJavaClassname() is the way to go. This would not remove characters like '-' but instead replace them with '_'. Which would be a potential problem for scripts which somehow already had such a class with an underscore - but such systems would already break under BSF anyway. Any objections? I also think the method should be moved into some util class outside of BSF and then called from BSF and wherever else it is needed.
        Hide
        blackdrag blackdrag added a comment -

        If we change the name it is not bijective any more. Well, being bijective is nice, but maybe not needed. Though having 2 possible source names for a given class name is one thing, having many more possibilities another. As soon as you have one script depending on another, that kind of name mangling will cause a problem. In https://blogs.oracle.com/jrose/entry/symbolic_freedom_in_the_vmsuggests to use an escaping mechanism instead. But the problem is that '-' is not part of that. Still we could take the idea and for example use
        + UTF16 hexadecimal number. That would then allow a 1:1 encoding and supports any UTF16 character

        Show
        blackdrag blackdrag added a comment - If we change the name it is not bijective any more. Well, being bijective is nice, but maybe not needed. Though having 2 possible source names for a given class name is one thing, having many more possibilities another. As soon as you have one script depending on another, that kind of name mangling will cause a problem. In https://blogs.oracle.com/jrose/entry/symbolic_freedom_in_the_vmsuggests to use an escaping mechanism instead. But the problem is that '-' is not part of that. Still we could take the idea and for example use + UTF16 hexadecimal number. That would then allow a 1:1 encoding and supports any UTF16 character

          People

          • Assignee:
            Unassigned
            Reporter:
            Tran The Trong
          • Votes:
            2 Vote for this issue
            Watchers:
            2 Start watching this issue

            Dates

            • Created:
              Updated: