I found a strange issue with java8 :
In a class method I have the following code :
int id;
...
new Key<Integer>(id)
To remove the "Redundant specification of type arguments " as the Key, I write :
new Key<>(id)
Then I get a
java.lang.VerifyError: Bad type on operand stack
At execution time...!!!! The reason : the compiler omits to replace the int by an Integer...
Hope this will help guys like me who were completly dispointed by such runtime exeption with their program just passing from java7 to java8....
Version: Luna Release (4.4.0)
Build id: 20140612-0600
Java version "1.8.0_25"
Java(TM) SE Runtime Environment (build 1.8.0_25-b17)
Java HotSpot(TM) 64-Bit Server VM (build 25.25-b02, mixed mode)
ADDED
Here is a complete simple example :
package bug;
public class Bug {
public static void main(String[] args) {
Bug.class.getConstructors();
System.out.println("test ok");
}
public Bug() {
BugCondition("", new Key<Integer>(1));
//BugCondition("", new Key<>(1));
}
public static final <C extends Object> void BugCondition(C test, Key<?> key) {
}
public class Key<K> {
public Key(K value) {
}
}
}
Seems the issue came from the generics (replace C by String):
public static final <C extends Object> void BugCondition(C test, Key<?> key) {
}
Your example compiles perfectly fine with Eclipse Mars. I'm using the following build:
Version: Mars Release Candidate 2 (4.5.0RC2)
Build id: 20150528-0540
I suspect this issue has been resolved in the meantime (like many other Eclipse/Java8 compilation issues)
Related
I am trying to convert a Gradle-based Elastic Search plugin project to Maven, and from ES 7.1.1 to ES 7.16.3
The project has an ESClientYamlSuiteTestCase-based integration test suite:
public class MyPluginTestSuiteIT extends ESClientYamlSuiteTestCase {
public MyPluginTestSuiteIT(#Name("yaml") ClientYamlTestCandidate testCandidate) {
super(testCandidate);
}
#ParametersFactory
public static Iterable<Object[]> parameters() throws Exception {
return ESClientYamlSuiteTestCase.createParameters();
}
}
There is a yaml file src/test/resources/test/10_basic.yml with the test directives.
How do I run those tests from maven?
When running equalsverfier in quarkus dev mode, equalsverfier tests fail.
I tried to test a class with equalsverifier. This works in my IDE.
I tried to use it in quarkus dev mode (by running ./mvnw quarkus:dev), but then it fails with the following exception:
ERROR [io.qua.test] (Test runner thread) Test DingetjeTest#implementsEquals() failed
: java.lang.AssertionError: EqualsVerifier found a problem in class a.Dingetje.
-> Can not set final java.lang.String field a.Dingetje.text to a.Dingetje
For more information, go to: http://www.jqno.nl/equalsverifier/errormessages
at nl.jqno.equalsverifier.api.SingleTypeEqualsVerifierApi.verify(SingleTypeEqualsVerifierApi.java:308)
at a.DingetjeTest.implementsEquals(DingetjeTest.java:11)
Caused by: java.lang.IllegalArgumentException: Can not set final java.lang.String field a.Dingetje.text to a.Dingetje
at java.base/jdk.internal.reflect.UnsafeFieldAccessorImpl.throwSetIllegalArgumentException(UnsafeFieldAccessorImpl.java:167)
at java.base/jdk.internal.reflect.UnsafeFieldAccessorImpl.throwSetIllegalArgumentException(UnsafeFieldAccessorImpl.java:171)
at java.base/jdk.internal.reflect.UnsafeFieldAccessorImpl.ensureObj(UnsafeFieldAccessorImpl.java:58)
at java.base/jdk.internal.reflect.UnsafeQualifiedObjectFieldAccessorImpl.get(UnsafeQualifiedObjectFieldAccessorImpl.java:38)
at java.base/java.lang.reflect.Field.get(Field.java:418)
at nl.jqno.equalsverifier.internal.reflection.FieldModifier.lambda$copyTo$1(FieldModifier.java:79)
at nl.jqno.equalsverifier.internal.reflection.FieldModifier.lambda$change$3(FieldModifier.java:113)
at nl.jqno.equalsverifier.internal.util.Rethrow.lambda$rethrow$0(Rethrow.java:47)
at nl.jqno.equalsverifier.internal.util.Rethrow.rethrow(Rethrow.java:30)
at nl.jqno.equalsverifier.internal.util.Rethrow.rethrow(Rethrow.java:45)
at nl.jqno.equalsverifier.internal.util.Rethrow.rethrow(Rethrow.java:55)
at nl.jqno.equalsverifier.internal.reflection.FieldModifier.change(FieldModifier.java:113)
at nl.jqno.equalsverifier.internal.reflection.FieldModifier.copyTo(FieldModifier.java:79)
at nl.jqno.equalsverifier.internal.reflection.InPlaceObjectAccessor.copyInto(InPlaceObjectAccessor.java:43)
at nl.jqno.equalsverifier.internal.reflection.InPlaceObjectAccessor.copy(InPlaceObjectAccessor.java:24)
at nl.jqno.equalsverifier.internal.checkers.ExamplesChecker.checkSingle(ExamplesChecker.java:84)
at nl.jqno.equalsverifier.internal.checkers.ExamplesChecker.check(ExamplesChecker.java:47)
at nl.jqno.equalsverifier.api.SingleTypeEqualsVerifierApi.verifyWithExamples(SingleTypeEqualsVerifierApi.java:413)
at nl.jqno.equalsverifier.api.SingleTypeEqualsVerifierApi.performVerification(SingleTypeEqualsVerifierApi.java:369)
at nl.jqno.equalsverifier.api.SingleTypeEqualsVerifierApi.verify(SingleTypeEqualsVerifierApi.java:304)
... 1 more
Here's the class under test:
package a;
import java.util.Objects;
public class Dingetje {
private final String text;
public Dingetje(String text) {
this.text = text;
}
#Override
public final boolean equals(Object o) {
if (this == o) return true;
if (!(o instanceof Dingetje)) {
return false;
}
Dingetje other = (Dingetje) o;
return text.equals(other.text);
}
#Override
public final int hashCode() {
return Objects.hash(text);
}
}
And the test:
package a;
import nl.jqno.equalsverifier.EqualsVerifier;
import org.junit.jupiter.api.Test;
class DingetjeTest {
#Test
void implementsEquals() {
EqualsVerifier.forClass(Dingetje.class)
.withNonnullFields("text")
.verify();
}
}
What am I missing here?
EqualsVerifier uses Objenesis to create instances of classes, and it keeps the same reference of the objenesis object around for performance reasons. It caches all the objects it has created before, so that makes things quicker when you want to create the same object over and over again, which EqualsVerifier tends to do.
However, EqualsVerifier keeps a static reference to objenesis, which means that it lives as long as the JVM does. It turns out that the Quarkus test runner can re-run the same tests again and again, and it creates a new class loader each time. But part of the equality of java.lang.Class is that the classloader that created the class, must also be the same. So it couldn't retrieve these objects from its cache anymore and returnd instances with classloaders that are now different from the other objects created in the test, and this caused the exceptions that you saw.
In version 3.8 of EqualsVerifier (created as a result of this StackOverflow post), this issue can be avoided by adding #withResetCaches() like this:
EqualsVerifier.forClass(Dingetje.class)
.withResetCaches()
.withNonnullFields("text")
.verify();
That fixes the problem.
I am writing a gradle script that runs all tests before making a build.
test {
filter {
includeTestsMatching "*TestAll*"
includeTestsMatching "*ExtensionValidatorTest*"
........
}
}
I have three tests of different versions(v1,v2,v3).
TestAll.java
package .....v1;//v2 for version 2 and v3 for version 3
#RunWith(Suite.class)
#Suite.SuiteClasses({
A.class,
B.class,
......
})
public class TestAll {
#BeforeClass
public static void setUp() {//connection to database
........
}
#AfterClass
public static void tearDown() {//close database connection
........
}
}
When I run gradle test connection to database is broken after execution of a particular TestAll. I do not want to change the TestAll files of any version as they can be run and tested independently. How can I make gradle run only setUp once(of any version)which establishes connection, then run all the TestAll method in v1,v2 and v3 and finally teardown(of any version) which terminates database connection.
Gradle won't help you with this. There are following methods in Gradle DSL:
test {
beforeSuite{...}
afterSuite{...}
}
However, they execute outside of the test runtime scope and intended for logging. You only can achieve this using a testing framework.
TestNG provides a simple solution - #BeforeSuite and #AfterSuite annotations, that are actually run once before and after the entire suite.
Unfortunately, JUnit doesn't have a built-in solution for that, since test isolation is its core concept. Nevertheless, you still can make your own. You need to encapsulate database-related API into a singleton class:
public class DbContainer() {
private static DbContainer container;
private DbContaner() {}
public DbContainer getInstance() {
if (container == null) {
container = new DbContainer()
}
return container;
}
public void openConnection() {
// ...
}
public void closeConnection() {
// ...
}
// here is your database API methods
}
Then you can share this instance between test methods and classes using #ClassRule annotation:
#ClassRule
public static DbContainer db = DbContainer.getInstance();
#Test
public void someTest() {
db.query(...)
}
Note: provided solution is not thread-safe and doesn't suit the parallel execution. Some additional effort is required to achieve it.
I know this has been asked multiple times... but I can't seem to find a solution.
Taken from this official guidelines example: https://openjfx.io/openjfx-docs/#gradle
I went on and added in my build.gradle :
plugins {
id 'application'
id 'org.openjfx.javafxplugin' version '0.0.8'
}
javafx {
version = '13'
modules = ['javafx.controls']
}
repositories {
mavenCentral()
}
mainClassName = "MyImage"
jar {
manifest {
attributes "Main-Class": "$mainClassName"
}
from {
configurations.runtimeClasspath.collect { it.isDirectory() ? it : zipTree(it) }
}
}
which, by running gradle jar (or gradle build), should actually produce a jar which should include all the packages it builds it with, that is the entire javafx library.
However, when it builds successfully and then I proceed with running:
java -jar build/libs/MyImage.jar
it still throws the error:
Error: JavaFX runtime components are missing, and are required to run this application
What am I missing?
(I use JDK 11)
Many Thanks.
In Java 11 the Java launcher detects that you're extending javafx.application.Application and checks the modules are present. If you're using plain old JARs then you'll get the error
Error: JavaFX runtime components are missing, and are required to run this application
You have two choices. Setup your application to use the Java module system or the following workaround.
This workaround avoids the Java launcher check and will let the application run.
public class MyImage { // <=== note - does not extend Application
public static class YourRealApplication extends Application {
#Override
public void start(Stage primaryStage) throws Exception {
// whatever...
}
}
public static void main(String[] args) {
Application.launch(YourRealApplication.class);
}
}
I run the following command
wsimport -s ..\Code\app\src\main\java http://localhost:9080/shortbus/ShortbusService/ShortbusService.wsdl
This runs and generates code, however, when I try to compile given the new code I get...
...\ShortbusService_Service.java:[43,8] cannot find symbol
symbol : constructor Service(java.net.URL,javax.xml.namespace.QName,javax.xml.w
s.WebServiceFeature[])
location: class javax.xml.ws.Service
I tried explicitly adding the jaxws-api.jar and rt.jar but neither seemed to work. can someone help with what I am missing?
Update
If I manually edit to (notice the comments)...
public ShortbusService_Service(WebServiceFeature... features) {
//super(__getWsdlLocation(), SHORTBUSSERVICE_QNAME, features);
super(__getWsdlLocation(), SHORTBUSSERVICE_QNAME);
}
public ShortbusService_Service(URL wsdlLocation) {
super(wsdlLocation, SHORTBUSSERVICE_QNAME);
}
public ShortbusService_Service(URL wsdlLocation, WebServiceFeature... features) {
//super(wsdlLocation, SHORTBUSSERVICE_QNAME, features);
super(wsdlLocation, SHORTBUSSERVICE_QNAME);
}
public ShortbusService_Service(URL wsdlLocation, QName serviceName) {
super(wsdlLocation, serviceName);
}
public ShortbusService_Service(URL wsdlLocation, QName serviceName, WebServiceFeature... features) {
//super(wsdlLocation, serviceName, features);
super(wsdlLocation, serviceName);
}
It compiles but I would rather not do this.
The code that's being generated by WAS 8.5's wsimport will generate code that is compatible with JAX-WS 2.2, because WAS 8.5 supports JAX-WS 2.2.
It seems that you are trying to compile your code against JAR files that represent an earlier version of JAX-WS, such as 2.0 or 2.1 (the Service constructor receiving "features" was added in JAX-WS 2.2).
So, you have two options:
Change your IDE settings (if you're using RAD, you'll probably have to migrate to a later RAD version) so your project compiles against the WAS 8.5 runtime; or
Use the -target switch for wsimport, providing the value 2.1 or 2.0. That will generate code that can be compiled against older versions of JAX-WS.