I have a project with the following lombok.config file:
lombok.accessors.chain = true
lombok.accessors.fluent = true
So the following class should compile fine:
#Data class A {
private int i;
public static void main(String[] args) {
new A().i();
}
}
and it does when compiling with javac. But Intellij (with or without the lombok plugin) shows a compilation error and the auto completion suggests using getI() which does not exist.
How can I fix this?
I think you're facing issue 53.
As a workaround, you could use #Accessors:
#Accessors(fluent = true) // order matters
#Data
class A {
private int i;
public static void main(String[] args) {
new A().i();
}
}
compile fine here (IntelliJ 14.0.3, lombok-plugin 0.8.9)
Related
I have two java files under the tests directory.
I use the following code to set up Soot for further analysis(i.e., construct a call graph) but meet an error of are the packages set properly?.
Main.java:
public class Main {
static void setupSoot() {
Options.v().set_prepend_classpath(true);
Options.v().set_process_dir(Collections.singletonList("./tests"));
Options.v().set_whole_program(true);
Scene.v().loadNecessaryClasses();
}
// Following function also doesn't work and has a similar error message
//static void setupSoot() {
// Options.v().set_prepend_classpath(true);
// Options.v().set_process_dir(Collections.singletonList("./tests"));
// Scene.v().loadClassAndSupport("FooBar");
//}
public static void main(String[] args) {
setupSoot();
// ....
}
}
And I get the following error message:
Exception in thread "main" java.lang.RuntimeException: Error: couldn't find class: FooBar are the packages set properly?
at soot.JastAddInitialResolver.resolveFromJavaFile(JastAddInitialResolver.java:119)
at soot.JavaClassSource.resolve(JavaClassSource.java:69)
at soot.SootResolver.bringToHierarchyUnchecked(SootResolver.java:253)
at soot.SootResolver.bringToHierarchy(SootResolver.java:221)
at soot.SootResolver.bringToSignatures(SootResolver.java:292)
at soot.SootResolver.bringToBodies(SootResolver.java:332)
at soot.SootResolver.processResolveWorklist(SootResolver.java:171)
at soot.SootResolver.resolveClass(SootResolver.java:141)
at soot.Scene.loadClass(Scene.java:1009)
at soot.Scene.loadClassAndSupport(Scene.java:994)
at soot.Scene.loadNecessaryClasses(Scene.java:1822)
at Main.setupSoot(Main.java:18)
at Main.main(Main.java:21)
If I complie two test files into .class files then I will get following error message:
Exception in thread "main" soot.SootResolver$SootClassNotFoundException: couldn't find class: tests.FooBar (is your soot-class-path set properly?)
at soot.SootResolver.bringToHierarchyUnchecked(SootResolver.java:245)
at soot.SootResolver.bringToHierarchy(SootResolver.java:221)
at soot.SootResolver.bringToSignatures(SootResolver.java:292)
at soot.SootResolver.bringToBodies(SootResolver.java:332)
at soot.SootResolver.processResolveWorklist(SootResolver.java:171)
at soot.SootResolver.resolveClass(SootResolver.java:141)
at soot.Scene.loadClass(Scene.java:1009)
at soot.Scene.loadClassAndSupport(Scene.java:994)
at soot.Scene.loadNecessaryClasses(Scene.java:1822)
at Main.setupSoot(Main.java:18)
at Main.main(Main.java:21)
I beleive that soot prepend_classpath is true since it works well when two test files are not in the package (i.e., remove package tests from both files).
Two files in tests directory are as follows:
Pack.java:
package tests;
public class Pack {
public static void main(String[] args) {
int s = 10;
}
}
FooBar.java
package tests;
public class FooBar {
public static void main(String[] args) {
FooBar callFooBar = new FooBar();
callFooBar.foo(10);
}
void foo(int a) {
bar(a);
}
void bar(int a) {
for (int i = 0; i < a; i++) {
i += a;
}
}
}
I solved this problem. The issue is that the path of the test files is wrong.
Now my project structure is as follows:
-ProjectRoot
|--src
|--Main.java
|--testers
|--easycase
|--FooBar.java
|--Pack.java
and My Main.java:
public class Main {
static void setupSoot() {
Options.v().set_prepend_classpath(true);
// Options.v().set_soot_classpath("xxxxx:xxxxx/xxxxx.jar") // For external packages
Options.v().set_process_dir(Collections.singletonList("./testers"));
Options.v().set_whole_program(true);
Scene.v().loadNecessaryClasses();
}
public static void main(String[] args) {
setupSoot();
Scene.v().loadAndSupport("esaycase.FooBar");
// Do something here
}
}
Note that the first line is package easycase; for both test files.
I ve been looking into CDI to simplify the code, and I ve been trying to use it with Java EE 8. I an trying to replicate an existing exemple without success. I was wondering if anyone might have experienced the same issue:
The PoolManager Class:
import javax.ejb.Startup;
import javax.ejb.Singleton;
import javax.annotation.PostConstruct;
#Singleton
#Startup
public class PoolManager {
private Queue<Object> pooledObjects;
#PostConstruct
private void init() {
System.out.println("Hi");
pooledObjects = new LinkedBlockingQueue<Object>(1_000);
for (int i = 0; i <= 1000; i++) {
pooledObjects.offer(i);
}
}
public void returnObject(Object o) {
pooledObjects.offer(o);
}
public Object borrowObject() {
return pooledObjects.poll();
}
}
the UsePoolManager Class:
public class UsePoolManager {
#Inject
private PoolManager poolManager;
public void usePooledObject() {
Object object = this.poolManager.borrowObject();
System.out.println(object);
}
}
and the Main:
public static void main(String[] args) {
UsePoolManager user = new UsePoolManager();
user.usePooledObject();
}
}
The injection doesn t seem to be working at all at runtime. I have no beans xml (i understand it is not necessary, and adding it didnt change anything.).
Any help would be greatly appreciated.
Thanks!
Checking whether I am using SE or EE for clarification...
You need to run that in JavaEE container like JBoss or Tomcat, not like standalone JavaSE application (with publis static void main)
For the sake of argumentation, using the CDI 2 container for Java SE:
in Gradle:
// https://mvnrepository.com/artifact/org.jboss.weld.se/weld-se-core
compile group: 'org.jboss.weld.se', name: 'weld-se-core', version: '3.0.4.Final'
public class CDI2Fire {
public static void main(String[] args) {
SeContainerInitializer initializer =
SeContainerInitializer.newInstance();
try (SeContainer container = initializer.disableDiscovery().addPackages(CDI2Fire.class).initialize()) {
container.select(UsePoolManager.class);
}
}
}
#ApplicationScoped
public class UsePoolManager {
#Inject
private PoolManager poolManager;
public void init(#Observes #Priority(Interceptor.Priority.APPLICATION - 100)
#Initialized(ApplicationScoped.class) Object init) throws Exception{
usePooledObject();
}
public void usePooledObject() {
Object object = this.poolManager.borrowObject();
System.out.println(object);
}
}
#Singleton
#Startup
public class PoolManager {
private Queue<Object> pooledObjects;
#PostConstruct
private void init() {
System.out.println("Hi");
pooledObjects = new LinkedBlockingQueue<Object>(1_000);
for (int i = 0; i <= 1000; i++) {
pooledObjects.offer(i);
}
}
public void returnObject(Object o) {
pooledObjects.offer(o);
}
public Object borrowObject() {
return pooledObjects.poll();
}
}
Regarding you own answer: you changed the complete application logic by moving the business method call usePooledObject() into the initialization listener instead of calling it manually as in the original example.
This is probably not the best idea, as objects which wildly run on arbitrary initialization events are very hard to control.
Thus: the point that you probably missed is, using get() after select():
try (SeContainer ...) {
// replaces the original "new":
UsePoolManager user = CDI.current().select(UsePoolManager.class).get();
user.usePooledObject();
}
Further note, that the use of CDI.current() eliminates the necessity to have a concrete container reference in scope. Thus, you can use it everywhere in your application as long as the container is active.
I'd like to put native Java objects into the ScriptEngine bindings for easier access.
I mean to avoid lots of Java.type(...).
I tried in that way.
jsEngine.getContext().getBindings(ScriptContext.ENGINE_SCOPE).put("manager", Manager.getInstance());
But that's failed with error "Manager has no such function "funcName" in eval...".
Is it possible at all?
UPD:
Example code
public class ManagerClass {
public void test()
{
System.out.println("Hello");
}
public static void test2()
{
System.out.println("Hello Static");
}
}
public class NewClass {
public static void main(String[] args) throws ScriptException {
final ScriptEngine s = new ScriptEngineManager().getEngineByExtension("js");
s.getBindings(ScriptContext.ENGINE_SCOPE).put("manager", new ManagerClass());
s.eval("manager.test(); manager.test2();");
}
}
Solved.
The correct way is
s.eval("manager.test(); manager.class.static.test2();");
I have never used JUnit before and I'm having some trouble setting up the tests. I have a Java project and a package, both named 'Project1' with one class which I'm trying to test called 'Module'. At the moment I'm just wanting to check if the values are correct.
Module class
package Project1;
//This class represents a module
public class Module {
public final static int MSC_MODULE_PASS_MARK = 50;
public final static int UG_MODULE_PASS_MARK = 40;
public final static int MSC_MODULE_LEVEL = 7;
public final static int STAGE_3_MODULE_LEVEL = 6;
private String moduleCode;
private String moduleTitle;
private int sem1Credits;
private int sem2Credits;
private int sem3Credits;
private int moduleLevel;
public Module(String code, String title, int sem1, int sem2, int sem3, int level)
{
moduleCode = code;
moduleTitle = title;
sem1Credits = sem1;
sem2Credits = sem2;
sem3Credits = sem3;
moduleLevel = level;
}
//method to return the module code
public String getCode()
{
return moduleCode;
}
//INSERT A BUNCH OF GET METHODS
}
Test case
Here is where I get lost. I'm trying to give some dummy values to test but I'm not sure how to pass the instance of Module to test.
package Project1;
import static org.junit.Assert.*;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;
public class TestCase {
#BeforeClass
public static void setUpBeforeClass() throws Exception {
}
#Before
public void setUp() throws Exception {
Module csc8001 = new Module("CSC8001", "Programming and data structures", 20, 0, 0, 7);
}
#Test
public void test() {
if (csc8001.getCode() == "CSC8001") {
System.out.println("Correct");
}
else{
fail("Not yet implemented");
}
}
}
Make your Module variable an instance variable in your test class, instead of a local variable in a method. Then the #Before method will just initialize the variable, not declare it too. Then it will be in scope in any #Test method.
Incidentally, compare your string contents with String's equals method, not ==.
import static org.junit.Assert.assertEquals;
public class TestCase {
private final Module csc8001 = new Module("CSC8001", "Programming and data structures", 20, 0, 0, 7);
#Test
public void testGetCode() {
assertEquals("Some error message", "CSC8001", csc8001.getCode()) ;
}
}
Always use equals:
if (csc8001.getCode().equals("CSC8001")) {
furthermore declare csc8001 as a class member.
public class TestCase {
private Module csc8001;
and
#Before
public void setUp() throws Exception {
csc8001 = new Module("CSC8001", "Programming and data structures", 20, 0, 0, 7);
}
Make your Module an instance variable. Remember that for each separate #Test method, JUnit will create a separate instance of your test class and run all of your #Before methods on it. Though you can instantiate your system under test in the same place you declare it, it may be advantageous to keep it in #Before as you have it.
public class TestCase {
private Module csc8001;
#Before public void setUp() throws Exception {
csc8001 = new Module("CSC8001", "Programming and data structures", 20, 0, 0, 7);
}
#Test public void test() { /* ... */ }
}
You can also use assertEquals to check equality, which will automatically fail with a clear message if the parameters don't match.
#Test
public void codeShouldEqualCSC8001() {
assertEquals("CSC8001", csc8001.getCode());
}
See assertEquals and more at the org.junit.Assert documentation.
p.s. Remember that the prefix test and the name setUp are holdovers from JUnit 3, and that using JUnit4 or better (with annotations like #Before and #Test) you are free to add multiple #Before and #After methods and give all your methods unconstrained names.
I have method for which I need to create a JUnit test:
public class MyClass {
private String file1;
private String file2;
public void myMethodSpaceCheck(){
if (new File(file1).size() > new File(file2).size() {
throw new Exception .....
}
}
}
Is it possible to use Mockito to create that JUnit test?
When dealing with files in Java, my preferred option is to go with Apache VFS, as I can then treat them as any other POJO. Obviously, that's a lot of work when you are already stuck with the File API.
Another option is to forget Mockito entirely and write those files on the system. I usually avoid that, as it sometimes make it harder to have tests run in parallel on some systems.
For this specific situation, my solution is generally to provide a special class, say FileBuilder, that can instantiate new Files:
public class FileBuilder {
public java.io.File newFile(String pathname) {
return new java.io.File(pathname);
}
}
I then mock this class before passing it to MyClass, and instrument it as appropriate:
#Test(expected = Exception.class)
public void should_fail_when_file1_is_bigger_than_file2() {
FileBuilder mockFile1 = file(2L);
FileBuilder mockFile2 = file(1L);
FileBuilder mockFileBuilder = mock(FileBuilder.class);
when(mockFileBuilder.newFile("file1").thenReturn(mockFile1);
when(mockFileBuilder.newFile("file2").thenReturn(mockFile2);
new MyClass(mockFileBuilder).myMethodSpaceCheck();
}
private static File file(long length) {
File mockFile = mock(File.class);
when(mockFile.length()).thenReturn(length);
return mockFile;
}
(your example mentions File.size(); I assumed you meant File.length())
The actual implementation of MyClass would look like this:
public class MyClass {
private String file1;
private String file2;
private final FileBuilder fileBuilder;
public MyClass() {
this(new FileBuilder());
}
#VisibleForTesting
MyClass(FileBuilder fileBuilder) {
this.fileBuilder = fileBuilder;
}
public void myMethodSpaceCheck() //...
}