3

I'm trying to do something that should be pretty easy but some how I keep failing...

the idea is to take existing java class from java repository (in our case java sun) modify it a bit.. recompile the class and use the modified class in our project

the steps (I took String.java from java.lang for example)

  1. modify String String.java by adding:

    public int zzz() {
           return 123;
       }
    

    just under the class constructors.

  2. recompile String.java

    javac -d String String.java
    
  3. jar -cf the compiled files this is the the result of: jar -vtf String.jar:

     0 Wed May 22 10:31:06 IDT 2013 META-INF/
    68 Wed May 22 10:31:06 IDT 2013 META-INF/MANIFEST.MF
    9763 Wed May 22 10:30:44 IDT 2013 java/lang/String$1.class
    1232 Wed May 22 10:26:04 IDT 2013 java/lang/String$CaseInsensitiveComparator.class
    17269 Wed May 22 10:26:04 IDT 2013 java/lang/String.class
    
  4. write short main class:

      public class main {
    
    /**
     * @param args
     */
    public static void main(java.lang.String[] args) {
        // TODO Auto-generated method stub
        java.lang.String s = new java.lang.String(" xxx ");
        s = s.concat("bla bla");
        System.out.println(s);
        System.out.println(s.zzz());
    
        }
    
    }   
    

(I get the same behavior when trying java.lang.String and just String.)

5.compile my main.java with the modified String class

    javac -Xbootclasspath/p:String.jar main.java

6.run main

java -Xbootclasspath/p:String.jar main

that gives us the following output:

myusername@machinename:~/work/sand_box$ java -Xbootclasspath/p:String.jar main
 xxx bla bla
Exception in thread "main" java.lang.NoSuchMethodError: java.lang.String.<init>([CZ)V
    at java.lang.Integer.toString(Integer.java:333)
    at java.lang.Integer.toString(Integer.java:136)
    at java.lang.String.valueOf(String.java:2948)
    at java.io.PrintStream.print(PrintStream.java:597)
    at java.io.PrintStream.println(PrintStream.java:736)
    at main.main(main.java:12)

I can't figure out what am I doing wrong can someone please shed some light on this please?

10x to all the contributors out there.

Gal Mazor
  • 100
  • 2
  • 10
  • are you trying to recompile `String` class without any of the related classes it requires on the classpath? – vikingsteve May 22 '13 at 08:17
  • @vikingsteve doesn't javac takes all the required classes from the jdk that is in use? in my case: java version "1.7.0_11" Java(TM) SE Runtime Environment (build 1.7.0_11-b21) Java HotSpot(TM) 64-Bit Server VM (build 23.6-b04, mixed mode) /usr/lib/jvm/java-7-oracle/jre/bin/java – Gal Mazor May 22 '13 at 08:45
  • Interesting point, but since you are trying to recompile a class from the jdk I would suppose that all jdk source would have to be in place (?) – vikingsteve May 22 '13 at 08:48
  • I think there is no chance to override a bootstrap class, as there is clear precedence of jar files within the same class loader. The loading depends on which jar is already open. Now rt.jar will be open and String is found there. So why even look into String.jar at all? I think the only way is to patch rt.jar – Bernd Ebertz May 22 '13 at 09:49

1 Answers1

0


From my pt of view it would be better to just extend String instead of recompiling a modified version of a JDK class
e.g.: public class String extends java.lang.String
That way you'll create a new String class in your package
Of course, depending on your needs this may not be the best option
But in general I think it's no good idea to modify JDK classes directly - at least if you don't plan to include (and recompile) all the SDK from source by yourself

KR
Florian

FloF
  • 1,167
  • 9
  • 7
  • So what exactly are your need then? – FloF May 26 '13 at 14:48
  • I want to override an existing java class the reason for overriding and not extend is because – Gal Mazor May 29 '13 at 09:44
  • Hi @FloF , sorry on the delay ... I'm trying to test an idea that instead of making lots of big changes in a big project I could take only one class modify some class methods in it and recompile it. If I will extend java.lang.String I will need to change all the references in my project from java.lang.String to String. something I prefer to avoid... – Gal Mazor May 29 '13 at 09:56