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

NullPointerException when using Spoon #1191

Closed
hylhp opened this issue Feb 18, 2017 · 10 comments
Closed

NullPointerException when using Spoon #1191

hylhp opened this issue Feb 18, 2017 · 10 comments
Labels

Comments

@hylhp
Copy link

hylhp commented Feb 18, 2017

Hi, I use spoon 5.5.0 under Ubuntu with jvm7. The experiment I did is:

  1. write a CatchProcess following the doc in http://spoon.gforge.inria.fr/first_analysis_processor.html
  2. compile it with javac and run it.
    Everything works well.

But if I delete the generated spooned dir and CatchProcess.java, NPE is thrown as following:

Exception in thread "main" java.lang.NullPointerException
	at org.eclipse.jdt.internal.compiler.batch.FileSystem.<init>(FileSystem.java:141)
	at org.eclipse.jdt.internal.compiler.batch.Main.getLibraryAccess(Main.java:3086)
	at spoon.support.compiler.jdt.JDTBatchCompiler.getUnits(JDTBatchCompiler.java:107)
	at spoon.support.compiler.jdt.JDTBasedSpoonCompiler.buildUnits(JDTBasedSpoonCompiler.java:410)
	at spoon.support.compiler.jdt.JDTBasedSpoonCompiler.buildUnitsAndModel(JDTBasedSpoonCompiler.java:372)
	at spoon.support.compiler.jdt.JDTBasedSpoonCompiler.buildSources(JDTBasedSpoonCompiler.java:348)
	at spoon.support.compiler.jdt.JDTBasedSpoonCompiler.build(JDTBasedSpoonCompiler.java:119)
	at spoon.support.compiler.jdt.JDTBasedSpoonCompiler.build(JDTBasedSpoonCompiler.java:102)
	at spoon.Launcher.buildModel(Launcher.java:700)
	at spoon.Launcher.run(Launcher.java:651)
@surli
Copy link
Collaborator

surli commented Feb 21, 2017

I'm not sure to understand your problem here: if you deleted the file CatchProcess.java and you use it in your program it seems natural that you've an error, no? Or do I miss something?

@surli surli added the bug label Feb 21, 2017
@hylhp
Copy link
Author

hylhp commented Feb 21, 2017

I compiled CatchProcess.java and got CatchProcess.class.
Then I think we don't need CatchProcess.java to run spoon. Is it right?
I encounter this problem when I tar the generated classes into a jar file and try to run spoon with this jar file.

@surli
Copy link
Collaborator

surli commented Feb 21, 2017

Then I think we don't need CatchProcess.java to run spoon. Is it right?

You're right, you don't need it to run Spoon if it's already compiled.
But if you're trying to pass Spoon sources as input to spoon, then you need all classes, except if you use the specific "no-classpath" mode.

I assume you're using a command line like that to run spoon:
java -classpath /path/to/binary/of/your/processor.jar:spoon-core-5.5.0-jar-with-dependencies.jar spoon.Launcher -i /path/to/src/of/your/project -p fr.inria.gforge.spoon.processors.CatchProcessor

Then what's your input project (-i argument)?

@hylhp
Copy link
Author

hylhp commented Feb 21, 2017

My input project is MapReduce framework source code (in a different dir from the dir of CatchProcess.java).

At the beginning, I tried to launch spoon inside the main function. But it throws above NPE error.
So I step back again and again to the official example.

How can I launch spoon only with the generated class files?

@surli
Copy link
Collaborator

surli commented Feb 21, 2017

The easiest way is certainly to use the maven plugin: https://github.com/SpoonLabs/spoon-maven-plugin

You can also get the jar-with-dependencies from the latest release: https://github.com/INRIA/spoon/releases/download/spoon-core-5.5.0/spoon-core-5.5.0-jar-with-dependencies.jar and to call it specifying in the classpath, the path of your compiled processor:

java -classpath /path/to/package/of/your/binary/processor/:spoon-core-5.5.0-jar-with-dependencies.jar spoon.Launcher -i /path/to/src/of/your/project -p fr.inria.gforge.spoon.processors.CatchProcessor

@hylhp
Copy link
Author

hylhp commented Feb 21, 2017

Thanks for the reply.
Now I think spoon also requires processor source file as input. Is it correct?
I use gradle instead of maven.

Another thing is: I try to replace a method parameter (add one more parameter).
In http://spoon.gforge.inria.fr/template_definition.html, it shows an example about how to do such replacement. But the method body also replaces to empty.
How to keep such method body unchanged?

@surli surli added question and removed bug labels Feb 22, 2017
@surli
Copy link
Collaborator

surli commented Feb 22, 2017

I use gradle instead of maven.

There's also a gradle plugin for Spoon: https://github.com/SpoonLabs/spoon-gradle-plugin :)

Now I think spoon also requires processor source file as input. Is it correct?

We assume in our example that you created and installed a maven/gradle project locally containing your processor: basically you create a maven project with your new processor and necessary dependencies, and you locally install it with mvn install. Then you use a dependency to your new module as explained there: https://github.com/SpoonLabs/spoon-gradle-plugin#how-to-add-processors

In http://spoon.gforge.inria.fr/template_definition.html, it shows an example about how to do such replacement. But the method body also replaces to empty.
How to keep such method body unchanged?

You should be able to do it by using the .S() method. Could you give an example of your code?

@hylhp
Copy link
Author

hylhp commented Feb 22, 2017

Very cool!

My task is to add parameter to existing methods and keep all other things the same.
I push my code to the github: https://github.com/hylhp/Spoon-example
Now, I can add parameter and copy method body. But there are two problems:

  1. Hello.java has two classes. After transmission, only the public class exists in the generated java file.
  2. How to keep method return type, thrownType the same?

Thanks again for your help.

@surli
Copy link
Collaborator

surli commented Feb 27, 2017

Hello.java has two classes. After transmission, only the public class exists in the generated java file.

Actually you should have another file for the second class in the output. If you want to keep the same CompilationUnit you can use the following option:

[--output-type <output-type>]
        States how to print the processed source code:
        nooutput|classes|compilationunits (default: classes)

with value "compilationunits".

How to keep method return type, thrownType the same?

I did not understand your question there: if I execute your code, currently nothing happens during the substition, I obtain exactly the same print method. What do you want to do there?

surli added a commit to surli/spoon that referenced this issue Feb 27, 2017
@surli
Copy link
Collaborator

surli commented Mar 10, 2017

@hylhp actually you were right: there was a deeply hidden bug in Spoon which occured only when using Spoon in an empty directory (i.e. without any .java files in it).
We fixed it in #1208 and the patch will be integrated in the next release which should be done by the end of the next week.

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

2 participants