I'm looking into a source code of Hibernate Search and stumbled into a piece of code which I don't really understand.
There is a static block calling a static method of org.hibernate.search.engine.Version class. I suspect it might be related to JIT but not sure how.
Could you please explain?
public class ImmutableSearchFactory implements ExtendedSearchIntegratorWithShareableState, WorkerBuildContext {
static {
Version.touch();
}
Version class:
public final class Version {
private Version() {
//now allowed
}
public static String getVersionString() {
return Version.class.getPackage().getImplementationVersion();
}
static {
LoggerFactory.make( MethodHandles.lookup() ).version( getVersionString() );
}
public static void touch() {
}
}
Here is the link to GihHub
If the Version class was already loaded, Version.touch(); won't do anything.
If the Version class was not loaded, Version.touch(); will trigger the loading, which in turn will trigger the execution of the following block of static code within the Version class:
static {
LoggerFactory.make( MethodHandles.lookup() ).version( getVersionString() );
}
... which will log the Hibernate Search version.
So the call to Version.touch(); is only there to make sure the Hibernate Search version is logged before Hibernate Search boots.
Related
I've included my code below. Following some other examples, I even tried to dynamically load the class in order to force it to run the static block, but that doesn't solve my problem. The class is loaded and class.getName() is printed successfully, but still, when it gets to the last line in the main method it throws an error saying the array is null.
All the other answers address things which don't seem to apply here, like how using the "final" keyword can allow the compiler to skip static blocks. Any help is appreciated!
package helper;
public class StaticTest {
public static boolean [] ALL_TRUE;
private static void setArray(){
ALL_TRUE = new boolean[8];
for(int i=0;i<ALL_TRUE.length;i++){
ALL_TRUE[i] = true;
}
}
static {
setArray();
}
public static void main(String [] args){
ClassLoader cLoader = StaticTest.class.getClassLoader();
try{
Class aClass = cLoader.loadClass("helper.StaticTest");
System.out.println("aClass.getName() = " + aClass.getName());
} catch(ClassNotFoundException e){
e.printStackTrace(System.out);
}
System.out.println(StaticTest.ALL_TRUE[0]);
}
}
In case anyone else lands here, the problem was that I had checked the Netbeans option "Compile on Save" (under Build->Compiling). Somehow, compiling files immediately upon saving was preventing the static block from being run.
Again, thanks to everyone who chimed in to verify that the code itself worked as expected.
Is there a way to execute "AfterAllTests" action within JUnit 5? E.g. close connection to db, close embedded kafka cluster, etc.
P.S. There is a way to do some preconditions before all tests with help of extension like that:
public class BeforeAfterExtension implements BeforeAllCallback, AfterAllCallback {
private static boolean FLAG = Boolean.TRUE;
...
#Override
public void beforeAll(ExtensionContext extensionContext) {
log.info("~~~~~~~~~~~~~~~~~~ BeforeAll setup ~~~~~~~~~~~~~~~~~~");
if (FLAG) {
// some code here
FLAG = Boolean.FALSE;
}
}
#Override
public void afterAll(ExtensionContext extensionContext) {
// ??
}
But no way for "After" tasks.
Yes you can use below mentioned code.
#AfterAll
static void afterAllIAmCalled() {
System.out.println("---Inside after finishing all testsDownAll---");
}
Link for you: https://www.concretepage.com/testing/junit-5/junit-5-beforeall-and-afterall-example
Updating answer further based on your need of running after all sets. Define your tests in suite as shown below
#RunWith(Suite.class)
# Suite.SuiteClasses({
SuiteTest1.class,
SuiteTest2.class,
})
public class JunitTest {
// This class remains empty, it is used only as a holder for the above annotations but as you need to perform action at the end of it do as mentioned below
#AfterSuite
Private void methodName(){
//my suite end action
}
}
Replied on mobile. Might not be symmetric answer but will solve your problem.
This should work for you.
My installer is storing some information in a singleton class during the installation process. Now, I have noticed that in elevated action, the singleton class does not have the same instance. So far, I have not found any workaround/solution so that they share the same instance. So, I have decided to make sure that if anyone wants to get an instance of the singleton, they must call from an unelevated environment. Let's say the singleton looks like the following:
public class InvestigatorReport {
private final List<Report> reports = new ArrayList<>();
private final static InvestigatorReport INSTANCE = new InvestigatorReport();
private InvestigatorReport() {
MyLogger.logInfo(getClass(), "initiating...");
}
public static InvestigatorReport getInstance(Context context) {
if (context.hasBeenElevated()) {
throw new IllegalAccessError(
"this method must be called unelevated!");
}
return INSTANCE;
}
private boolean addReport(Report report) {
return reports.add(report);
}
}
But the problem is, There are some cases when I have to call this add report from an action class that is elevated. So I have tried the following in my elevated action class:
if (context.hasBeenElevated()) {
return (Boolean) context.runUnelevated(new RemoteCallable() {
#Override
public Serializable execute() {
return getInstance(context).addReport(report);
}
});
}
But, as you can see if I am passing the same context object from the elevated action class to the RemoteCallable class so, even though I am running the class unelevated, the context.hasBeenElevated() still returns true.
Is there any other way that I can check the elevation level other than the context? If you have any other better idea on preventing anyone from calling the singleton getInstance() method, I am all ears.
I would use a different pattern. Make all methods of your singleton static and wrap the data access with runUnelevated calls:
public static boolean addReport(Report report, Context context) {
context.runUnelevated(new RemoteCallable() {
#Override
public Serializable execute() {
InvestigatorReport.reports.add(report);
return null;
}
});
}
In that way, you can call the methods from both elevated and unelevated code without having to check anything at the call site.
I'm investigating the reason why the following scenario causes NoClassDefFoundError, which involves the use of jmockit and JNI.
Here's the classes:
MyJNI.class
class MyJNI {
MyJNI() {}
public static final native int getInt();
}
MyTestInterface.class
public interface MyTestInterface {
int INT_FROM_JNI = MyJNI.getInt();
}
MyTestImp.class
public class MyTestImp implements MyTestInterface {
public MyTestImp() {}
}
DummyTest.java
#RunWith(JMockit.class)
public class DummyTest {
#Mocked
MyTestInterface myTest;
#Test
public void dummy() { assertTrue(true); }
}
FailingTest.java
#RunWith(JMockit.class)
public class FailingTest {
#Mocked
MyTestImp myTest;
#Test
public void shouldPass() { assertTrue(true); }
}
If we run DummyTest.java and FailingTest.java in sequence (the order matters), the test in FailingTest.java fails with the error message "java.lang.NoClassDefFoundError: xxx.xxx.xxx.MyTestInterface".
Specifically, any of the following change corrects the error:
(a) running the tests in reverse order: FailingTest.java and then DummyTest.java
(b) in "DummyTest.java", change "MyTestInterface myTest;" to "MyTestImp myTest;"
(c) in "MyTestInterface.class", change "int INT_FROM_JNI = MyJNI.getInt();" to "int INT_FROM_JNI = 1;".
(d) in "FailingTest.java", change "MyTestImp myTest;" to "MyTestInterface myTest;"
I couldn't find a good explanation to this. In this case the unit tests are not independent anymore. It looks like in the scenario mock MyTestInterface would cause problem in the other test files when trying to use MyJNI, and in this case would make MyTestInterface not found in runtime.
Anyone has any clues of how to explain this? Thanks!
I downloaded and installed play framework 2.0.2 and then created a project. I eclipsified the project and opened it in eclipse.
I have a class called Application which extends Controller class. In most examples around the web, I see controllers like the following.
public class Application extends Controller {
public static void index() {
render(arg0,arg1,...);
}
public static void tasks() {
render(arg0,arg1,...);
}
public static void newTask() {
render(arg0,arg1,...);
}
public static void deleteTask(Long id) {
render(arg0,arg1,...);
}
}
However in my default application, I can only do the following. I don't know how to do the previous one.
public class Application extends Controller {
public static Result index() {
return ok("Hello World!");
}
public static Result tasks() {
return ok(indexabc.render("hello world"));
}
public static Result newTask() {
return TODO;
}
public static Result deleteTask(Long id) {
return TODO;
}
}
In my code when I try to replace "Result" return type with "void", there is no problem. However, when I want to call "render()" method with some parameters, that method doesn't exist. I can't find a way for how to call render function.
The examples you are seeing around the Web are for Play 1.x, and the version you have got in your Controller is for Play 2.x.
Play 1 used render(), play 2 returns a Result object, which is created from calling the ok() method or a number of other methods.
You have 2 options at this point. Download Play 1.2.5 (current stable release) and use the examples you have found, or use the Play 2.x documentation and search for Play 2.x examples.