Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 5 months ago.
Improve this question
I’m mid-way though writing a Minecraft 1.18.2 mod (Forge 40.1.80).
As this is the first Minecraft mod I am writing, I’m not too experienced in the field and have no idea what is causing this issue. When I try running the code I get this error (4 times): java: no suitable constructor found for Block(net.minecraft.world.level.block.state.BlockBehaviour.Properties). Any help would be greatly appreciated. The error appears here: "() -> new Block(ORE_PROPERTIES <-Here"
package com.example.factorytechv0_1.startup;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.world.item.BlockItem;
import net.minecraft.world.item.Item;
import net.minecraft.world.level.block.state.BlockBehaviour;
import net.minecraft.world.level.material.Material;
import net.minecraftforge.eventbus.api.IEventBus;
import net.minecraftforge.fml.javafmlmod.FMLJavaModLoadingContext;
import net.minecraftforge.registries.DeferredRegister;
import net.minecraftforge.registries.ForgeRegistries;
import net.minecraftforge.registries.RegistryObject;
import org.openjdk.nashorn.internal.ir.Block;
public class Registration {
private static final DeferredRegister<Block> BLOCKS = DeferredRegister.create((ResourceLocation) ForgeRegistries.BLOCKS, "factorytechv0_1");
private static final DeferredRegister<Item> ITEMS = DeferredRegister.create(ForgeRegistries.ITEMS, "factorytechv0_1");
public static void init() {
IEventBus bus = FMLJavaModLoadingContext.get().getModEventBus();
BLOCKS.register(FMLJavaModLoadingContext.get().getModEventBus());
ITEMS.register(FMLJavaModLoadingContext.get().getModEventBus());
}
public static final BlockBehaviour.Properties ORE_PROPERTIES = BlockBehaviour.Properties.of(Material.STONE).strength(2f);
public static final Item.Properties ITEM_PROPERTIES = new Item.Properties().tab(ModSetup.ITEM_GROUP);
public static final RegistryObject<Block> CHROME_ORE_OVERWORLD = BLOCKS.register("chrome_ore_overworld", () -> new Block(ORE_PROPERTIES));
public static final RegistryObject<Item> CHROME_ORE_OVERWORLD_ITEM = fromBlock(CHROME_ORE_OVERWORLD);
public static final RegistryObject<Block> CHROME_ORE_DEEPSLATE = BLOCKS.register("chrome_ore_deepslate", () -> new Block(ORE_PROPERTIES));
public static final RegistryObject<Item> CHROME_ORE_DEEPSLATE_ITEM = fromBlock(CHROME_ORE_DEEPSLATE);
public static final RegistryObject<Block> HAFNIUM_ORE_NETHER = BLOCKS.register("hafnium_ore_nether", () -> new Block(ORE_PROPERTIES));
public static final RegistryObject<Item> HAFNIUM_ORE_NETHER_ITEM = fromBlock(HAFNIUM_ORE_NETHER);
public static final RegistryObject<Block> TECHNETIUM_ORE_END = BLOCKS.register("technetium_ore_end", () -> new Block(ORE_PROPERTIES));
public static final RegistryObject<Item> TECHNETIUM_ORE_END_ITEM = fromBlock(TECHNETIUM_ORE_END);
public static <B extends Block> RegistryObject<Item> fromBlock(RegistryObject<B> block)
{
return ITEMS.register(block.getId().getPath(), () -> new BlockItem(block.get(), ITEM_PROPERTIES));
}
}
Here is the main initialisation file for the mod (if needed)
package com.example.factorytechv0_1;
import com.example.factorytechv0_1.startup.ClientSetup;
import com.example.factorytechv0_1.startup.ModSetup;
import com.example.factorytechv0_1.startup.Registration;
import com.mojang.logging.LogUtils;
import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.eventbus.api.IEventBus;
import net.minecraftforge.fml.DistExecutor;
import net.minecraftforge.fml.common.Mod;
import net.minecraftforge.fml.javafmlmod.FMLJavaModLoadingContext;
import org.slf4j.Logger;
// The value here should match an entry in the META-INF/mods.toml file
#Mod("factorytechv0_1")
public class factorytechv0_1 {
// Directly reference a slf4j logger
private static final Logger LOGGER = LogUtils.getLogger();
public factorytechv0_1() {
// Register the deferred reg
Registration.init();
// Register the setup method for Modloading
IEventBus modbus = FMLJavaModLoadingContext.get().getModEventBus();
modbus.addListener(ModSetup::init);
DistExecutor.unsafeRunWhenOn(Dist.CLIENT, () -> () -> modbus.addListener(ClientSetup::init));
}
}
I think you might have the wrong import, perhaps intellij/eclipse suggested the wrong one for you.
import org.openjdk.nashorn.internal.ir.Block
This import looks weird, please remove it and replace it with something starting with net.minecraft.world.item.
Had a fast look at the API 1.18.2 , the class is abstract.
Here there is a little bit more to it, this shows how
https://moddingtutorials.org/o19/basic-blocks
What it is occurs when calling a new instance is BlockBehaviour.Properties is static but assigning it to the constructor argument instantly makes it an instance reference "no longer static" but it's methods are static, to overcome that, during construction the .of() method is called by that syntax notation and the properties are set "of the class" while the static state is being assigned to the constructor argument, in the hierarchy is a BlockBehaviour.Properties and is the copy of that instance available(for lack of better expression because it's static and only one copy).
After it is passed into the constructor, all the higher classes it extends have a constructor argument must be passed into as BlockBehaviour.Properties type so the first line in your customised class will have super(theblockpropargref); the theblockpropargref variable is now an instance and not static.
The looney point is the .of() method is called attached to the new instance customised class call but the BlockBehaviour.Properties is a class in the hierarchy of the new customised class so it searches it's own hierarchy for the .of() method signature and argument loading and finds it in it's own "static class" BlockBehaviour.Properties , the actual mad point is it must become an instance but must be called with a method to exist , but to not return a value from a method it must use a "void" method or be returning the type the instance variable is so it can only be assigned and exist during calling it before being made an instance of its type to be put on an instance variable teference
If you look at class Block it's used to "extend from" as normally an abstract class is used.
Now take a look at the API docs for Block class and near the top of page you can find "what that point is for" from the "list of known sub classes"
https://nekoyue.github.io/ForgeJavaDocs-NG/javadoc/1.18.2/net/minecraft/world/level/block/Block.html
Those are all bits and pieces that have unique properties and behaviours.
And at the bottom of the hierarchy where a class can be instantiated "new" here is an example API docs
https://nekoyue.github.io/ForgeJavaDocs-NG/javadoc/1.18.2/net/minecraft/world/level/block/DetectorRailBlock.html
There should be somewhere some proper Minecraft tutorial.
If you ever did make a new one you would extend from it to make a new one or cast type dependent if suitable.
It seems to be an enclosing static class wrapper but it has methods in its own level. However, it does contain static classes and those are simply called with their method to use , not instantiated new.
Related
This question already has answers here:
What does the 'static' keyword do in a class?
(22 answers)
Cannot make a static reference to the non-static method
(8 answers)
Closed 5 years ago.
For some reason when I'm trying to call methods using a main method or try changing variables declared outside the main method I get forced into having to change everything to static. This is fine in places but when it comes to needing to change values later in the code for example using a Scanner for input the main method just takes it to a whole new level trying to make me change the Scanner library etc.
This example shows what happens if I try calling a method.
This example shows what happens when I try alter the value of a variable declared outside my main method.
I have never faced an issue like this before when writing java code I've tried recreating the classes/ project files etc but nothing works. I've tried looking everywhere for a solution but I can't seem to find one probably due to the fact that I don't know what to search for. I've probably made myself look like a right idiot with my title haha! Any suggestions people?? Thanks in advance!
Maisy
It can be a bit confusing to get out of "static land" once you are in your main() method. One easy way is to have another object contain your "real" (non-static) top level code and then your main method creates that object and starts it off.
public static void main() {
MyEngine engine = new MyEngine();
// core logic inside of start()
engine.start();
}
I hope that this was clear enough for you. Good luck Maisy!
When calling methods form a main you have to instantiate the class they are in, unless it's a static function
this is because that a class is a sort of template and there is nothing saved about it before it get instantiated
public class TestClass{
public static void main(String[] args){
TestClass testClass = new TestClass();
testClass.method();
}
public method method(){}
}
in the example above i instantiated a TestClass and then called on the testClass instance
there is some functions and variables on classes you might want static, because a static on a class is shared between ALL instances, and can be called on the class, say you want to know how many instances were created then something like this can be done.
public class TestClass{
public static void main(String[] args){
TestClass testClass = new TestClass();
testClass.method();
System.out.print(TestClass.instances +""); // note that i call on
//the class and not on an instance for this static variable, and that the + ""
//is to cast the int to a string
}
public static int instances = 0; // static shared variable
public TestClass(){instances++;} // constructor
public method method(){}
}
You need to do some Object Oriented Programming tutorial and to learn some basic.
As answer for your problem to call without using static you have to create an instance of the main Class
let suppose the following class Foo
public class Foo{
private int myVarInteger;
public int getMyVarInteger(){ return this.myVarInteger;}
public void setMyVarInteger(int value){this.myVarInteger = value;}
public static void main(String[] args){
Foo myClassInstanceObject = new Foo();
// now we can access the methods
myClassInstanceObject.setMyVarInteger(5);
System.out.println("value ="+myClassInstance.getMyVarInteger());
}
}
This is a question from this book: https://www.cl.cam.ac.uk/teaching/0506/ConcSys/cs_a-2005.pdf page 28
Can you write an additional Java class which creates an
object that, when passed to the test method causes it to
print “Here!”? As I say in the code, editing the class A
itself, or using library features like reflection, serialization,
or native methods are considered cheating! I’ll provide
some hints in lectures if nobody can spot it in a week or
so. None of the PhD students has got it yet.
public class A {
// Private constructor tries to prevent A
// from being instantiated outside this
// class definition
//
// Using reflection is cheating :-)
private A() {
}
// ’test’ method checks whether the caller has
// been able to create an instance of the ’A’
// class. Can this be done even though the
// constructor is private?
public static void test(Object o) {
if (o instanceof A) {
System.out.println("Here!");
}
}
}
I know the question is a lot unclear. I can think of many different 'hack-ish' solutions but not sure if they will be counted as 'cheating' or not :)
I can't find the official answer so asking you for what would be a good answer.
If we consider that nesting class A does not "modify it" (as, technically, all lines of code are intact) then this solution is probably the only valid option:
class B
{
static
public class A {
// Private constructor tries to prevent A
// from being instantiated outside this
// class definition
//
// Using reflection is cheating :-)
private A() {
}
// ’test’ method checks whether the caller has
// been able to create an instance of the ’A’
// class. Can this be done even though the
// constructor is private?
public static void test(Object o) {
if (o instanceof A) {
System.out.println("Here!");
}
}
}
public static void main (String[] args) throws java.lang.Exception
{
A.test(new A());
}
}
What I mean is, technically it follows all the rules:
Can you write an additional Java class which creates an object that, when passed to the test method causes it to print “Here!”? - Done
As I say in the code, editing the class A itself ... considered cheating! - Technically, the class is unedited. I copy pasted it into my code.
... or using library features like reflection, serialization, or native methods are considered cheating! - Done
If, however, you decide that nesting class A should not be allowed, then I believe there is no proper solution to the problem given the current definition. Also, given the section of the book this task is given in, I bet that the author wanted to make the constructor protected but not private.
Somehow, I don't like this sort of questions. It's from a lecture back in 2005, and according to websearches, it seems that nobody has found "the" solution until now, and no solution has been published.
The constraints are clear, but the question of what is allowed or not is somewhat fuzzy. Every solution could be considered as "cheating", in one or the other way, because a class with a private constructor is not meant to be subclassed. That's a critical security mechanism, and the responsible engineers are working hard to make sure that this security mechanism cannot be trivially circumvented.
So of course, you have to cheat in order to solve this.
Nevertheless, I spent quite a while with this, and here's how I eventually cheated it:
1.) Download the Apache Bytecode Engineering Library, and place the bcel-6.0.jar in one directory.
2.) Create a file CreateB.java in the same directory, with the following contents:
import java.io.FileOutputStream;
import org.apache.bcel.Const;
import org.apache.bcel.generic.*;
public class CreateB
{
public static void main(String[] args) throws Exception
{
ClassGen cg = new ClassGen("B", "A", "B.java",
Const.ACC_PUBLIC | Const.ACC_SUPER, new String[] {});
ConstantPoolGen cp = cg.getConstantPool();
InstructionList il = new InstructionList();
MethodGen method = new MethodGen(Const.ACC_PUBLIC, Type.VOID,
Type.NO_ARGS, new String[] {}, "<init>", "B", il, cp);
il.append(InstructionFactory.createReturn(Type.VOID));
method.setMaxStack();
method.setMaxLocals();
cg.addMethod(method.getMethod());
il.dispose();
cg.getJavaClass().dump(new FileOutputStream("B.class"));
}
}
3.) Compile and execute this class:
javac -cp .;bcel-6.0.jar CreateB.java
java -cp .;bcel-6.0.jar CreateB
(note: On linux, the ; must be a :). The result will be a file B.class.
4.) Copy the class that was given in the question (verbatim - without any modification) into the same directory and compile it.
5.) Create the following class in the same directory, and compile it:
public class TestA
{
public static void main(String[] args)
{
A.test(new B());
}
}
6.) The crucial step: Call
java -Xverify:none TestA
The output will be Here!.
The key point is that the CreateB class creates a class B that extends A, but does not invoke the super constructor. (Note that an implicit super constructor invocation would normally be added by the compiler. But there's no compiler involved here. The bytecode is created manually). All this would usually fail with a VerifyError when the class is loaded, but this verification can be switched off with -Xverify:none.
So in summary:
The class A itself is not edited (and also its byte code is not edited, I hope this is clear!)
No reflection
No serialization
No custom native methods
There are a few options here:
Create a class:
public class Y extends A {
public static void main(String[] args) throws Exception {
X.test(new Y());
}
}
And then edit the bytecode and remove the call to X.. Of course this violates the JVM specification and has to be run with -Xverify:none as said above. This is essentially the same as the one #Marco13.
Option 2:
import sun.misc.Unsafe;
public class Y extends A {
public static void main(String[] args) throws Exception {
Unsafe uf = Unsafe.getUnsafe();
X.test((X) uf.allocateInstance(X.class));
}
}
Compile the code and run it by putting your classpath in the sysloader (otherwise it won't work):
$ java -Xbootclasspath/p:. Y
Both work for me :) Of course, they are both cheating. The first option isn't Java. The second is, well, evil :)
If I find out another way, I'll post it :)
In any case this can't be done without low-level tricks. The JVM Specification explicitly prohibits the creation of an object without calling the constructor as the object in the stack is uninitialized. And the JVM Specification explicitly prohibits not calling the super constructor. And the JVM Specification explicitly requires verification of access protection.
Still funny, though :)
Java can support unicode class name:)
The A in "if (o instanceof A)" could be different from the A in "public class A"
For example, the code below will print "Here!" instead of "bad".
A.java
public class A {
// Private constructor tries to prevent A
// from being instantiated outside this
// class definition
//
// Using reflection is cheating :-)
private A() {
// A: U+0041
}
// ’test’ method checks whether the caller has
// been able to create an instance of the ’A’
// class. Can this be done even though the
// constructor is private?
public static void test(Object o) {
if (o instanceof А) {
System.out.println("Here!");
}
}
}
А.java
public class А {
// A: U+0410, not A: U+0041
}
Main.java
public class Main {
public static void main(String[] args) {
A.test(new А());
}
}
This method is called regularly
public static void stynax(String N[]) {
if (N[1].equals("echo")) { echo.s(); main(); }
if (N[1].equals("detectos")) { detectos.s(); main(); }
if (N[1].equals("getuser")) { getuser.s(); main(); }
if (N[1].equals("exit")) { exit.s(); main(); }
if (N[1].equals("makefile")) { makefile.s(); main(); }
if (N[1].equals("cd")) { cd.s(); main(); }
if (N[1].equals("system")) { system.s(); main(); }
main();
}
How can I invoke all these methods
system.s();
echo.s();
Ect, by seeing if the class exists, then calling the corresponding method.
N[1] is always the class name. The class where this method is stored is in a class called main, and the classes that are called are in a different package called Commands.
I always seem to get this error, when trying to make a Class variable, i think this is the main issue.
at java.net.URLClassLoader.findClass(URLClassLoader.java:381)
So it never gets to invoke the method.
To simplify.
1) The program gets the class name as a String as N[1]
2) It sees if the class exists
3) If the class exists it calls it by the name of the class N[1].s();
Edit: Imports used
import java.io.ByteArrayOutputStream;
import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintStream;
import java.io.PrintWriter;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Arrays;
import cgameing.Commands.FileBrowser;
import cgameing.Commands.banner;
import cgameing.Commands.cd;
import cgameing.Commands.detectos;
import cgameing.Commands.echo;
import cgameing.Commands.exit;
import cgameing.Commands.getuser;
import cgameing.Commands.makefile;
import cgameing.Commands.system;
end of edit:
This one works, for anyone wanting to do the same thing
(Class.forName("commands."+N[1])).getDeclaredMethod("s", null).invoke(null,null);
Thanks everyone
You'll need to use reflection. Try something as follows. Use fully qualified class name instead of "XYZ" if your class is in a different package.
import java.lang.reflect.*;
import java.lang.*;
public class ReflectionTest {
public static void main(String[] args)throws NoSuchMethodException,
ClassNotFoundException,
IllegalAccessException,
InvocationTargetException {
(Class.forName("XYZ")).getDeclaredMethod("ABC", null).invoke(null,null);
}
}
class XYZ
{
public static void ABC()
{
System.out.println("Lulz");
}
}
For your use case given your classes are in commands package (as you stated in a comment). The fully qualified name will then be commands.classname
(Class.forName("commands."+N[1])).getDeclaredMethod("s", null).invoke(null,null);
You can use Reflection.
You have Class name coming in Array.
You can use "Class" and "Method" class. Class can determine if the class exists or not, and method can be used to call method you need to call.
try {
Class<?> c = Class.forName(N[1]);
Object t = c.newInstance();
Method[] allMethods = c.getDeclaredMethods();
for (Method m : allMethods) {
String mname = m.getName();
// if name matches use invoke method.
}
} catch (ClassNotFoundException x) {
//handle exception
}
Please consult API if you need to see more details.
I recommend you avoid using reflection if you possibly can. Better is to define the commands you expect to see - ideally in an enum.
For example:
enum Command {
CD(FileSystem::cd),
EXIT(Application::exit),
MAKEFILE(FileSystem::createFile),
...
private final Runnable runnable;
Command(Runnable runnable) {
this.runnable = runnable;
}
public void run() {
runnable.run();
}
}
You can still use the name to get the command if you wish (automatically throwing an exception if the value isn't found in the enum - which is presumably what you would want):
Command.valueOf(commandString.toUpperCase()).run();
Or call the commands directly without having to know which method they delegate to:
Command.MAKEFILE.run();
Given you are going to have a list of if statements somewhere, you might as well encapsulate that in an enum which is much more explicit than embedding the method names.
Okay, everyone seems to suggest reflection, there is at least one alternative way to do it, depending on whether you know your class and method names at compile time or not.
So, lets say we have this method in someclass:
public void changeDirectory(String args) {
//do something
}
If they are known, you could easily use method references:
HashMap<String, Consumer<String[]>> commands = new HashMap<>();
commands.put("cd", SomeClass::changeDirectory);
commands.get("cd").accept(args);
The drawback would be, the method signature would have to be the same... on the other hand, if you know the exact method anyway, you could just use a switch statement and call them directly...
If you want to do it dynamically, the alternative to reflection would be MethodHandles. The advantage is that they would only check access once on creation and have some other optimizations that should make them faster than reflection in most cases.
Class<?> dynamicallyFoundClass = Class.forName("some.package.SomeClass");
Class<?> fixedClass = SomeClass.class;
String methodName = "changeDirectory";
MethodType type = MethodType.methodType(void.class, String.class);
handles.put("cd", lookUp.findStatic(dynamicallyFoundClass, methodName, type));
handles.get("cd").invoke(args);
But how complicated an approach you have to use would depend on what you know at compile time and what has to be found at runtime.
The following code is generating an error on the variable con2 saying "non-static variable con2 cannot be referenced from a static context Error." I Googled for a resolution and they are suggesting the variable isn't initalized yet to make the methods available. Am I initializing this incorrectly? I also tried changing things to public but that didn't help either.
import java.io.*;
import java.net.*;
import java.sql.*;
import java.sql.CallableStatement;
import java.sql.ResultSet;
import java.sql.PreparedStatement;
import net.sourceforge.jtds.jdbcx.JtdsDataSource;
import net.sourceforge.jtds.jdbc.Driver;
class testconnect {
private java.sql.Connection con2 = null;
private final String url2 = "jdbc:jtds:sqlserver://";
private final String serverName= "SQL01";
private final String portNumber = "2677";
private final String databaseName= "App";
private final String userName = "bob";
private final String password = "boob";
private final String selectMethod = "cursor";
private String getConnectionUrl2(){
System.out.println("initalizing jtds");
//String returnVal = url+serverName+":"+portNumber+";databaseName="+databaseName+";user="+userName+";password="+password+";instance="+instance+";";
String returnVal = url2+serverName+":"+portNumber+"/"+databaseName+";user="+userName+";password="+password;
System.out.println("url2: " + returnVal);
return returnVal;
}
public static void main (String[] args) {
con2 = java.sql.DriverManager.getConnection(getConnectionUrl2());
}
} //end class
You probably want to add "static" to the declaration of con2.
In Java, things (both variables and methods) can be properties of the class (which means they're shared by all objects of that type), or they can be properties of the object (a different one in each object of the same class). The keyword "static" is used to indicate that something is a property of the class.
"Static" stuff exists all the time. The other stuff only exists after you've created an object, and even then each individual object has its own copy of the thing. And the flip side of this is key in this case: static stuff can't access non-static stuff, because it doesn't know which object to look in. If you pass it an object reference, it can do stuff like "thingie.con2", but simply saying "con2" is not allowed, because you haven't said which object's con2 is meant.
No, actually, you must declare your con2 field static:
private static java.sql.Connection con2 = null;
Edit: Correction, that won't be enough actually, you will get the same problem because your getConnection2Url method is also not static. A better solution may be to instead do the following change:
public static void main (String[] args) {
new testconnect().run();
}
public void run() {
con2 = java.sql.DriverManager.getConnection(getConnectionUrl2());
}
Java has two kind of Variables
a)
Class Level (Static) :
They are one per Class.Say you have Student Class and defined name as static variable.Now no matter how many student object you create all will have same name.
Object Level :
They belong to per Object.If name is non-static ,then all student can have different name.
b) Class Level :
This variables are initialized on Class load.So even if no student object is created you can still access and use static name variable.
Object Level:
They will get initialized when you create a new object ,say by new();
C)
Your Problem :
Your class is Just loaded in JVM and you have called its main (static) method : Legally allowed.
Now from that you want to call an Object varibale : Where is the object ??
You have to create a Object and then only you can access Object level varibales.
Your main() method is static, but it is referencing two non-static members: con2 and getConnectionUrl2(). You need to do one of three things:
1) Make con2 and getConnectionUrl2() static.
2) Inside main(), create an instance of class testconnect and access con2 and getConnectionUrl2() off of that.
3) Break out a different class to hold con2 and getConnectionUrl2() so that testconnect only has main in it. It will still need to instantiate the different class and call the methods off that.
Option #3 is the best option. #1 is the worst.
But, you cannot access non-static members from within a static method.
The simplest change would be something like this:
public static void main (String[] args) throws Exception {
testconnect obj = new testconnect();
obj.con2 = DriverManager.getConnection(obj.getConnectionUrl2());
obj.con2.close();
}
This is an interesting question, i just want to give another angle by adding a little more info.You can understand why an exception is thrown if you see how static methods operate.
These methods can manipulate either static data, local data or data that is sent to it as a parameter.why? because static method can be accessed by any object, from anywhere.
So, there can be security issues posed or there can be leaks of information if it can use instance variables.Hence the compiler has to throw such a case out of consideration.
The following code is generating an error on the variable con2 saying "non-static variable con2 cannot be referenced from a static context Error." I Googled for a resolution and they are suggesting the variable isn't initalized yet to make the methods available. Am I initializing this incorrectly? I also tried changing things to public but that didn't help either.
import java.io.*;
import java.net.*;
import java.sql.*;
import java.sql.CallableStatement;
import java.sql.ResultSet;
import java.sql.PreparedStatement;
import net.sourceforge.jtds.jdbcx.JtdsDataSource;
import net.sourceforge.jtds.jdbc.Driver;
class testconnect {
private java.sql.Connection con2 = null;
private final String url2 = "jdbc:jtds:sqlserver://";
private final String serverName= "SQL01";
private final String portNumber = "2677";
private final String databaseName= "App";
private final String userName = "bob";
private final String password = "boob";
private final String selectMethod = "cursor";
private String getConnectionUrl2(){
System.out.println("initalizing jtds");
//String returnVal = url+serverName+":"+portNumber+";databaseName="+databaseName+";user="+userName+";password="+password+";instance="+instance+";";
String returnVal = url2+serverName+":"+portNumber+"/"+databaseName+";user="+userName+";password="+password;
System.out.println("url2: " + returnVal);
return returnVal;
}
public static void main (String[] args) {
con2 = java.sql.DriverManager.getConnection(getConnectionUrl2());
}
} //end class
You probably want to add "static" to the declaration of con2.
In Java, things (both variables and methods) can be properties of the class (which means they're shared by all objects of that type), or they can be properties of the object (a different one in each object of the same class). The keyword "static" is used to indicate that something is a property of the class.
"Static" stuff exists all the time. The other stuff only exists after you've created an object, and even then each individual object has its own copy of the thing. And the flip side of this is key in this case: static stuff can't access non-static stuff, because it doesn't know which object to look in. If you pass it an object reference, it can do stuff like "thingie.con2", but simply saying "con2" is not allowed, because you haven't said which object's con2 is meant.
No, actually, you must declare your con2 field static:
private static java.sql.Connection con2 = null;
Edit: Correction, that won't be enough actually, you will get the same problem because your getConnection2Url method is also not static. A better solution may be to instead do the following change:
public static void main (String[] args) {
new testconnect().run();
}
public void run() {
con2 = java.sql.DriverManager.getConnection(getConnectionUrl2());
}
Java has two kind of Variables
a)
Class Level (Static) :
They are one per Class.Say you have Student Class and defined name as static variable.Now no matter how many student object you create all will have same name.
Object Level :
They belong to per Object.If name is non-static ,then all student can have different name.
b) Class Level :
This variables are initialized on Class load.So even if no student object is created you can still access and use static name variable.
Object Level:
They will get initialized when you create a new object ,say by new();
C)
Your Problem :
Your class is Just loaded in JVM and you have called its main (static) method : Legally allowed.
Now from that you want to call an Object varibale : Where is the object ??
You have to create a Object and then only you can access Object level varibales.
Your main() method is static, but it is referencing two non-static members: con2 and getConnectionUrl2(). You need to do one of three things:
1) Make con2 and getConnectionUrl2() static.
2) Inside main(), create an instance of class testconnect and access con2 and getConnectionUrl2() off of that.
3) Break out a different class to hold con2 and getConnectionUrl2() so that testconnect only has main in it. It will still need to instantiate the different class and call the methods off that.
Option #3 is the best option. #1 is the worst.
But, you cannot access non-static members from within a static method.
The simplest change would be something like this:
public static void main (String[] args) throws Exception {
testconnect obj = new testconnect();
obj.con2 = DriverManager.getConnection(obj.getConnectionUrl2());
obj.con2.close();
}
This is an interesting question, i just want to give another angle by adding a little more info.You can understand why an exception is thrown if you see how static methods operate.
These methods can manipulate either static data, local data or data that is sent to it as a parameter.why? because static method can be accessed by any object, from anywhere.
So, there can be security issues posed or there can be leaks of information if it can use instance variables.Hence the compiler has to throw such a case out of consideration.