I need to know if a java class import a package

Discussion in 'Java' started by Daniel, Apr 23, 2007.

  1. Daniel

    Daniel Guest

    Im writing a unit test class, and I want to check if a given class is
    importing some package (ie: java.util.Collections) from the code, is
    that posible?

    With this code
    Class a = myClass.getClass();
    System.out.println(a.getPackage());

    i can know the package of myClass, is there anything like this for
    imports statements?
     
    Daniel, Apr 23, 2007
    #1
    1. Advertising

  2. Daniel

    Eric Sosman Guest

    Daniel wrote On 04/23/07 10:20,:
    > Im writing a unit test class, and I want to check if a given class is
    > importing some package (ie: java.util.Collections) from the code, is
    > that posible?
    >
    > With this code
    > Class a = myClass.getClass();
    > System.out.println(a.getPackage());
    >
    > i can know the package of myClass, is there anything like this for
    > imports statements?


    Probably not, since `import' is just a compile-time
    convenience. You get the same byte code from

    class Foo {
    java.util.Set s;
    }

    and from

    import java.util.Set;
    class Foo {
    Set s;
    }

    and from

    import java.util.*;
    class Foo {
    Set s;
    }

    and from

    import java.util.*;
    import javax.swing.*;
    class Foo {
    Set s;
    }

    Why should your test plan care whether the source
    code uses fully-qualified class names or abbreviates
    them with the help of `import'?

    --
     
    Eric Sosman, Apr 23, 2007
    #2
    1. Advertising

  3. Daniel

    Daniel Guest

    Its true, but is there a way to know if certain class is used inside
    the tested class, despite if the developer declares them in the import
    or with the fully-qualified name?


    On Apr 23, 12:09 pm, Eric Sosman <> wrote:
    > Daniel wrote On 04/23/07 10:20,:
    >
    > > Im writing a unit test class, and I want to check if a given class is
    > > importing some package (ie: java.util.Collections) from the code, is
    > > that posible?

    >
    > > With this code
    > > Class a = myClass.getClass();
    > > System.out.println(a.getPackage());

    >
    > > i can know the package of myClass, is there anything like this for
    > > imports statements?

    >
    > Probably not, since `import' is just a compile-time
    > convenience. You get the same byte code from
    >
    > class Foo {
    > java.util.Set s;
    > }
    >
    > and from
    >
    > import java.util.Set;
    > class Foo {
    > Set s;
    > }
    >
    > and from
    >
    > import java.util.*;
    > class Foo {
    > Set s;
    > }
    >
    > and from
    >
    > import java.util.*;
    > import javax.swing.*;
    > class Foo {
    > Set s;
    > }
    >
    > Why should your test plan care whether the source
    > code uses fully-qualified class names or abbreviates
    > them with the help of `import'?
    >
    > --
    >
     
    Daniel, Apr 23, 2007
    #3
  4. Daniel

    Daniel Guest

    Eric, thanks for your help
    To clarify a little bit more my problem, I will try to add some
    example of what I'm needing:

    I need that some users fill with code in page to solve a task, this
    task involves the sorting of an array of integers, this could be
    easily solved with Collections.sort, but I gave them as a
    precondition, they couldn't use the Collections class (because I want
    to test if they can iterate an order an array by themselves).
    To correct this tasks, I have a Junit class that test against the
    submitted code, so I was searching for some mechanism that could help
    me with this.

    The webpage is an open community JavaBlackBelt.com

    Note: If this could be done, I imagine that also could be applied to
    test if the developers are using some classes that are not specified
    by the architecture. (eg: when developing J2ee code, sometimes the
    developers could use some classes from the app server that could
    decrease the portability)


    On Apr 23, 12:09 pm, Eric Sosman <> wrote:
    > Daniel wrote On 04/23/07 10:20,:
    >
    > > Im writing a unit test class, and I want to check if a given class is
    > > importing some package (ie: java.util.Collections) from the code, is
    > > that posible?

    >
    > > With this code
    > > Class a = myClass.getClass();
    > > System.out.println(a.getPackage());

    >
    > > i can know the package of myClass, is there anything like this for
    > > imports statements?

    >
    > Probably not, since `import' is just a compile-time
    > convenience. You get the same byte code from
    >
    > class Foo {
    > java.util.Set s;
    > }
    >
    > and from
    >
    > import java.util.Set;
    > class Foo {
    > Set s;
    > }
    >
    > and from
    >
    > import java.util.*;
    > class Foo {
    > Set s;
    > }
    >
    > and from
    >
    > import java.util.*;
    > import javax.swing.*;
    > class Foo {
    > Set s;
    > }
    >
    > Why should your test plan care whether the source
    > code uses fully-qualified class names or abbreviates
    > them with the help of `import'?
    >
    > --
    >
     
    Daniel, Apr 23, 2007
    #4
  5. Daniel

    Eric Sosman Guest

    Daniel wrote On 04/23/07 13:53,:
    > Eric, thanks for your help
    > To clarify a little bit more my problem, I will try to add some
    > example of what I'm needing:
    >
    > I need that some users fill with code in page to solve a task, this
    > task involves the sorting of an array of integers, this could be
    > easily solved with Collections.sort, but I gave them as a
    > precondition, they couldn't use the Collections class (because I want
    > to test if they can iterate an order an array by themselves).
    > To correct this tasks, I have a Junit class that test against the
    > submitted code, so I was searching for some mechanism that could help
    > me with this.
    >
    > The webpage is an open community JavaBlackBelt.com


    You could certainly inspect the compiled byte code for
    references to "forbidden" classes. The java.lang.instrument
    package might be helpful here.

    However, I doubt such an approach will be all that useful
    as a detector of cheating. To begin with, you need to make
    a useful list of banned classes -- For example, if I were
    told to sort an int[], I would use Arrays.sort() and never
    touch the Collections class at all. Also, the sources for
    Arrays (and Collections) are readily available; a cheater
    could simply copy the source and change the package names,
    and thus evade your detection.

    Finally, JUnit is probably not a good framework for
    this sort of thing. If I try to write an array-sorter but
    make an error and introduce an infinite loop, you're going
    to want some kind of timeout mechanism that prevents my
    blunder (or my sabotage!) from monopolizing your page until
    somebody notices the problem and restarts it. As far as
    I'm aware, JUnit has no such facility; it just runs tests
    until they finish or fail. If they do neither ...

    Various organizations have public web pages that run
    externally-submitted programs under controlled conditions,
    with provision for catching runaways, guarding against hacks,
    and so on. Instead of reinventing the wheel, I'd suggest
    you look up a few of those sites and find out what they're
    using for software; perhaps you can adapt something that
    already exists as opposed to building it all from scratch.

    > Note: If this could be done, I imagine that also could be applied to
    > test if the developers are using some classes that are not specified
    > by the architecture. (eg: when developing J2ee code, sometimes the
    > developers could use some classes from the app server that could
    > decrease the portability)


    Although this shares some aspects with the programming-
    assignment problem, I think it's fundamentally a different
    issue. There's no "antagonist" to worry about, and the
    body of code to be inspected is more or less "known," so I
    think static analysis of byte code (or source code) may be
    a more appropriate tool than black-box run-time testing.

    --
     
    Eric Sosman, Apr 23, 2007
    #5
  6. Eric Sosman wrote:
    > Daniel wrote On 04/23/07 13:53,:
    >> Eric, thanks for your help
    >> To clarify a little bit more my problem, I will try to add some
    >> example of what I'm needing:
    >>
    >> I need that some users fill with code in page to solve a task, this
    >> task involves the sorting of an array of integers, this could be
    >> easily solved with Collections.sort, but I gave them as a
    >> precondition, they couldn't use the Collections class (because I want
    >> to test if they can iterate an order an array by themselves).
    >> To correct this tasks, I have a Junit class that test against the
    >> submitted code, so I was searching for some mechanism that could help
    >> me with this.
    >>
    >> The webpage is an open community JavaBlackBelt.com

    >
    > You could certainly inspect the compiled byte code for
    > references to "forbidden" classes. The java.lang.instrument
    > package might be helpful here.
    >
    > However, I doubt such an approach will be all that useful
    > as a detector of cheating. To begin with, you need to make
    > a useful list of banned classes -- For example, if I were
    > told to sort an int[], I would use Arrays.sort() and never
    > touch the Collections class at all. Also, the sources for
    > Arrays (and Collections) are readily available; a cheater
    > could simply copy the source and change the package names,
    > and thus evade your detection.


    For completeness, note that a cheater could use reflection and run time
    string calculation to invoke Arrays.sort without any mention of it that
    would be visible to static analysis of the class. However, that would be
    technically more difficult than writing a sort.

    The most practical cheating method would indeed be to copy any known
    working sort method, not necessarily Arrays.sort, followed by a few
    minutes work with e.g. the Eclipse refactoring tools - change
    identifiers to protect the guilty, extract some methods...

    How about picking a programming task that does not have so many correct
    implementations lying around on the web?

    Patricia
     
    Patricia Shanahan, Apr 23, 2007
    #6
  7. Daniel

    Mark Space Guest

    Daniel wrote:
    > Eric, thanks for your help
    > To clarify a little bit more my problem, I will try to add some
    > example of what I'm needing:
    >
    > I need that some users fill with code in page to solve a task, this
    > task involves the sorting of an array of integers, this could be
    > easily solved with Collections.sort, but I gave them as a
    > precondition, they couldn't use the Collections class (because I want
    > to test if they can iterate an order an array by themselves).


    I didn't read everything, but I wonder if some form of dependancy
    injection would work here. You supply the object (let's call it
    SortTest) to sort, rather than allow them to declare one internally.

    Also, make each method call for SortTest, for a read or a write, record
    what is being done. So if they are supposed to be implementing a shell
    sort, you'll know if the reads and writes for the object are being done
    in the correct order. This could be useful feedback for the student, to
    point out common errors. If on the other hand they read each element
    once, in order, then write them back once, in the sorted order, they are
    probably cheating.

    Rather than calling main, I think you'd have to define your own
    Interface, which the user would then implement. Do the compile and run
    both on your end, that way you can control which libraries are accessed.
    You could also define your own classloader, to deny access to certain
    classes by the user.
     
    Mark Space, Apr 23, 2007
    #7
  8. Hi!

    Thus spake Patricia Shanahan on 04/23/2007 09:53 PM:
    > For completeness, note that a cheater could use reflection and run time
    > string calculation to invoke Arrays.sort without any mention of it that
    > would be visible to static analysis of the class.


    You could certainly try and grep your way through the submitted
    source code to find those fragments.

    > However, that would be
    > technically more difficult than writing a sort.


    However, that would be technically more difficult than coming up
    with a more challenging task ;-)

    > How about picking a programming task that does not have so many correct
    > implementations lying around on the web?


    But seriously... I always hated tasks like that which forced you to
    reinvent the wheel... I think I might have used exactly the approach
    you mentioned above... it might have been difficult, but I think I
    would have liked the idea of having circumvented a seemingly useless
    condition. ;-)

    Regards,

    Phil
     
    Philipp Taprogge, Apr 23, 2007
    #8
  9. Daniel

    Eric Sosman Guest

    Philipp Taprogge wrote:
    > Hi!
    >
    > Thus spake Patricia Shanahan on 04/23/2007 09:53 PM:
    >> For completeness, note that a cheater could use reflection and run time
    >> string calculation to invoke Arrays.sort without any mention of it that
    >> would be visible to static analysis of the class.

    >
    > You could certainly try and grep your way through the submitted
    > source code to find those fragments.


    I'm not sure whether it would be equivalent to the Halting
    Problem, but it certainly could be difficult:

    StringBuffer buff =
    new StringBuffer("kbwb/vujm/Bssbzt");
    for (int i = 0; i < buff.length; ++i)
    buff.setCharAt(i, buff.charAt(i) - 1);
    Class c = Class.forName(buff.toString());
    ...

    It's occurred to me that loading the "foreign" class with
    a customized ClassLoader might be the start of a way to intercept
    such dodges. It still wouldn't defend against the far simpler
    cheat of copying the freely-available source code of Arrays.sort
    and giving it a new name.

    --
    Eric Sosman
    lid
     
    Eric Sosman, Apr 24, 2007
    #9
  10. Eric Sosman wrote:
    > Philipp Taprogge wrote:
    >> Hi!
    >>
    >> Thus spake Patricia Shanahan on 04/23/2007 09:53 PM:
    >>> For completeness, note that a cheater could use reflection and run time
    >>> string calculation to invoke Arrays.sort without any mention of it that
    >>> would be visible to static analysis of the class.

    >>
    >> You could certainly try and grep your way through the submitted
    >> source code to find those fragments.

    >
    > I'm not sure whether it would be equivalent to the Halting
    > Problem, but it certainly could be difficult:
    >
    > StringBuffer buff =
    > new StringBuffer("kbwb/vujm/Bssbzt");
    > for (int i = 0; i < buff.length; ++i)
    > buff.setCharAt(i, buff.charAt(i) - 1);
    > Class c = Class.forName(buff.toString());
    > ...


    Or, really simple and effective, just xor "java.util.Arrays" with a
    random bit pattern, and store both bit pattern and the result. The byte
    code would contain two apparently random arrays of char, but their xor
    would be the original string.

    Patricia
     
    Patricia Shanahan, Apr 24, 2007
    #10
  11. Daniel

    Adam Maass Guest

    "Daniel" <> wrote:
    > Im writing a unit test class, and I want to check if a given class is
    > importing some package (ie: java.util.Collections) from the code, is
    > that posible?
    >
    > With this code
    > Class a = myClass.getClass();
    > System.out.println(a.getPackage());
    >
    > i can know the package of myClass, is there anything like this for
    > imports statements?
    >


    Short answer: no.

    Import statements simply tell the compiler where to look for types referred
    to by simple name. The imports do not exist in the .class file structure as
    indepedent entities.

    -- Adam Maass
     
    Adam Maass, Apr 28, 2007
    #11
  12. Daniel wrote:
    > I need that some users fill with code in page to solve a task, this
    > task involves the sorting of an array of integers, this could be
    > easily solved with Collections.sort, but I gave them as a
    > precondition, they couldn't use the Collections class (because I want
    > to test if they can iterate an order an array by themselves).
    > To correct this tasks, I have a Junit class that test against the
    > submitted code, so I was searching for some mechanism that could help
    > me with this.


    You need to get the classloader used to tell you.

    Here are a starting point:

    import java.net.URL;
    import java.net.URLClassLoader;

    public class TraceClassLoader extends URLClassLoader {
    public TraceClassLoader(String cp) throws Exception {
    super(new URL[] { new URL(cp) });
    }
    protected Class<?> loadClass(String name, boolean resolve) throws
    ClassNotFoundException {
    System.out.println(name);
    return super.loadClass(name, resolve);
    }
    public static void main(String[] args) throws Exception {
    Class.forName(args[0], true, new
    TraceClassLoader(args[1])).getMethod("main", new Class[] {
    String[].class }).invoke(null, new Object[] { new String[0] });
    }
    }

    import java.util.*;

    public class Foobar {
    public static void main(String[] args) throws Exception {
    List lst = new ArrayList();
    lst.add("CCC");
    lst.add("BB");
    lst.add("A");
    for(int i = 0; i < lst.size(); i++) {
    System.out.println(lst.get(i));
    }
    Collections.sort(lst);
    for(int i = 0; i < lst.size(); i++) {
    System.out.println(lst.get(i));
    }
    }
    }

    java TraceClassLoader Foobar file:/C:/

    Foobar
    java.lang.Object
    java.util.List
    java.lang.String
    java.lang.Exception
    java.util.ArrayList
    java.lang.System
    java.io.PrintStream
    CCC
    BB
    A
    java.util.Collections
    A
    BB
    CCC

    Arne

    PS: It is important that Foobar.class is not in the classpath where
    TraceClassLoader is running.
     
    =?ISO-8859-1?Q?Arne_Vajh=F8j?=, Apr 29, 2007
    #12
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Parvinder
    Replies:
    6
    Views:
    760
    Thomas G. Marshall
    Feb 27, 2005
  2. JPractitioner
    Replies:
    13
    Views:
    20,189
    Roedy Green
    Feb 24, 2006
  3. George P
    Replies:
    3
    Views:
    695
    Alex Martelli
    Sep 11, 2004
  4. Gabriel Rossetti
    Replies:
    1
    Views:
    503
    ryles
    Sep 20, 2009
  5. Andries

    I know, I know, I don't know

    Andries, Apr 23, 2004, in forum: Perl Misc
    Replies:
    3
    Views:
    253
    Gregory Toomey
    Apr 23, 2004
Loading...

Share This Page