Java, static variable doesn't initialize from outside of class - java

I have a class that all of its methods and variables are static. Class is like this:
public class LinkManager {
private static final String TAG = "LinkManager";
private static final String UAT = "http://uat.MY-Domain.com/";
private static final String PRODUCTION = "https://www.MY-Domain.com/api/";
private static String DOMAIN;
private static final String FACEBOOK_PROFILE_IMAGE_URL = "http://graph.facebook.com/###/picture?type=large";
private static final String FACEBOOK_WALL_URL = "https://graph.facebook.com/###/feed";
private static final String URL_LOGIN = DOMAIN + "login/";
private static final String URL_USER_PROFILE = DOMAIN + "user/";
private static final String URL_VENUE_LIST = DOMAIN + "venues/?centre_lat=###&centre_lon=####&radius=#####";
.
.
.
public static void setBackendMode(int mode) {
switch(mode) {
case 0:
DOMAIN = PRODUCTION;
Log.i(TAG, "Backend mode: Production");
break;
case 1:
DOMAIN = UAT;
Log.i(TAG, "Backend mode: UAT");
break;
default:
Log.e(TAG, "Fatal Error!!! Check you backend url. Selected mode is: " + mode);
}
}
public static String getFacebookProfileImageUrl(String userId) {
String str = FACEBOOK_PROFILE_IMAGE_URL;
str = str.replaceAll("###", userId);
return str;
}
public static String getFacebookWallUrl(String userId) {
String str = FACEBOOK_WALL_URL;
str = str.replaceAll("###", userId);
return str;
}
public static String getLoginUrl() {
return URL_LOGIN;
}
public static String getUserProfileUrl() {
return URL_USER_PROFILE;
}
public static String getVenueListUrl(String lat, String lng, String radius) {
String str = URL_VENUE_LIST;
str = str.replaceAll("###", lat);
str = str.replaceAll("####", lng);
str = str.replaceAll("#####", radius);
return str;
}
.
.
.
}
I have another class which is my main class. I want to initialize DOMAIN variable through this class. Since, I'm developing application for Android, onCreate() is the first method that invokes. This is my code:
public class MainScreen extends FragmentActivity {
private static final String TAG = "MainScreen";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Log.i(TAG, "*********************************");
Log.i(TAG, "Try to run ------- application...");
Log.i(TAG, "*********************************");
// Set Backend mode (Production or UAT)
LinkManager.setBackendMode(1);
...
}
}
Now, when I run the application log shows this output:
06-28 10:00:56.973: I/MainScreen(9014): *********************************
06-28 10:00:56.973: I/MainScreen(9014): Try to run ------- application...
06-28 10:00:56.973: I/MainScreen(9014): *********************************
06-28 10:00:56.973: I/LinkManager(9014): Backend mode: UAT
06-28 10:00:57.023: I/ContentDownloader(9014): Try to open=> nulluser/
Line 4 shows DOMAIN variable has initialized with UAT but after that when other classes invoke methods of LinkManager class DOMAIN contains null. Since DOMAIN is static variable I expect content of this variable should not be changed.
What/where is my mistake?
Any suggestion would be appreciated. Thanks

After you invoke setBackendMode() and before setBackendMode() is really executed, JVM will initialize URL_LOGIN, URL_USER_PROFILE, URL_VENUE_LIST, when DOMAIN is still null.
Solution:
Just do this:
public static String getLoginUrl() {
return DOMAIN + "login/";
}
public static String getUserProfileUrl() {
return DOMAIN + "user/";
}
public static String getVenueListUrl(String lat, String lng, String radius) {
String str = DOMAIN + "venues/?centre_lat=###&centre_lon=####&radius=#####";
// ...
}

It is because
private static final String URL_USER_PROFILE = DOMAIN + "user/";
Is executed before DOMAIN is set in setBackendMode()

Related

Java newbie failing to call a string from an other class.java

I want to call a string, in client.java, from the main class of server.java file but miserably failing...
Any help would be appreciated
Please make an example so my stupid brain can understand it...
package whatever.user.locahost.server;
public class Server {
public static void main(String[] args) {
//
int portNumber = 666;
boolean socketActive = false;
public static String serverDomain = "DOMAIN NAME";
}
}
//In client.java main class
...
ServerDomainGetter serverDomain = new ServerServerDomainGetter(serverDomain);
String serverDomainGetter = serverDomain;
String clientDomain = "ClientDomain.uk"; //TODO read from file
String clientUserName = "Demo";
...
So the client.java class cannot access a non static class level variable from server.java the way you are trying to access it. Also can't use the final modifier if you want to make it static.
public static String serverDomain = "DOMAIN NAME"
If you instantiate the variable like that in the server.java class then you will be able to access it the way you are trying to access it.
More information on statics:
https://codegym.cc/groups/posts/141-10-things-you-need-to-know-about-the-static-modifier-in-java
Declaring public static String serverDomain = "domain.uk" should be outside the main. Posting the final code below. HUGE thanks to #isaace
public class Server {
public static String serverDomain = "domain.uk";
public static void main(String[] args) {
int portNumber = 666;
String serverDomain = "domain.uk";
System.out.println(serverDomain);
}}
public class Client {
public static void main(String[] args) {
System.out.println("Server domain: " + Server.serverDomain);
String clientDomain = "ClientDomain.uk ";
String clientUserString = "Demo";
System.out.println("Client Domain: "+ clientDomain + " clientUser: "+clientUserString);
}}

Getters Not Working Properly

I am working on a report file to call multiple methods to function on an external Reporting file. Below is my report.java file and the getter elements do not seem to be working. These elements are generateReport and isServerActive. This is what I am trying to figure out as all of my other methods when called work properly, but these two still seem to be getting hung up.
class Report {
//Variables to be used within my methods/functions below
private static String serverName;
private static String userName;
private static String password;
private String reportName;
private int numParameters;
private int reportParameter;
private String reportParameterString;
private static String outputType;
private static String systemName;
private static String genReport;
private static boolean active;
// Constructor
Report(String name){
reportName = name;
}
//setServerName method, assigned variable serverName the value passed into "name"
public static void setServerName(String name){
serverName = name;
}
//setUserName method, assigned variable userName the value passed into "user"
public static void setUserName(String user){
userName = user;
}
//setPassword method, assigned variable password the value passed into "pw"
public static void setPassword(String pw){
password = pw;
}
//setNumParameters method, assigned variable numParameters the value
passed into int "numParm"
public void setNumParameters (int numParm){
numParameters = numParm;
}
//setParameter method, assigned variable reportParameter the value
passed into int "reportParam"
//Assigned variable reportParameterString the value passed into
"param"
public void setParameter (int reportParam, String param){
reportParameter = reportParam;
reportParameterString = param;
}
//setOutputType method, assigned variable outputType the value passed
into "output"
public void setOutputType (String output){
outputType = output;
}
//setReportSystemName method, assigned variable systemName the value
passed into "reportSystemName"
public void setReportSystemName (String reportSystemName){
systemName = reportSystemName;
}
public void generateReport(String reportGen){
genReport = reportGen;
}
public void isServerActive(boolean isActive){
active = isActive;
}
}
Here is the file in which I am calling all of the above methods
public class ReportClassPrinter {
public static void main(String[] args) {
//Set the server name
Report.setServerName("\\\\fancyServer");
Report.setUserName("NHAUser");
Report.setPassword("NHAPassword");
//Create the two reports
Report report1 = new Report("Report #1");
Report report2 = new Report("Report #2");
//Set the numbe of parameters for each report
report1.setNumParameters(2);
report2.setNumParameters(4);
//Add the needed parameters, Report should make sure I am not trying to break it
report1.setParameter(0, "01/01/1970");
report1.setParameter(1, "01/01/2018");
report1.setParameter(2, "pjdt");
report2.setParameter(0, "08/01/2017");
report2.setParameter(1, "08/01/2018");
report2.setParameter(2, "notpjdt");
report2.setParameter(3, "THIS IS A PARAMETER");
report2.setParameter(4, "THIS WON'T BE ADDED");
//Set the output type
report1.setOutputType("pdf");
report2.setOutputType("xls");
//Set the report system name:
report1.setReportSystemName("reportNumberOne.rdl");
report2.setReportSystemName("reportNumberTwo.rdl");
//Display the Report information
System.out.println(report1.generateReport());
System.out.println("Server up is: " + Report.isServerActive());
System.out.println(report2.generateReport());
System.out.println("Server up is: " + Report.isServerActive());
//Change the server - notice how chaning this once, affects ALL reports
System.out.println("\nUpdating Server information\n");
Report.setServerName("\\\\SercureServerName");
Report.setUserName("SecureNHAUser");
//Again display the Report information
System.out.println(report1.generateReport());
System.out.println("Server up is: " + Report.isServerActive());
System.out.println(report2.generateReport());
System.out.println("Server up is: " + Report.isServerActive());
}
}
You need
return statement at the last line of your getters
change return type of the function
delete parameter from the function signature since you don't call the functions with argument
add static to the return type
to work as you intended on Main function. What you did in your getters are just allocated value to the variable.
class Report {
[...]
public static String generateReport(){
return genReport;
}
public static boolean isServerActive(){
return active;
}
}

Best way to write Custom Exception

I am trying to write a custom exception with 3 constroctors. Can I initize final variables in 3 different constroctors? I am getting compilation errors. How to make this error free?
public class CrifServiceFaultException extends RuntimeException {
/**
*
*/
private static final long serialVersionUID = 1L;
public CrifServiceFaultException(String message) {
// // - The blank final field errorDescription may not have been
super(message);
}
public CrifServiceFaultException(String processCode,
String processDescription, String transformCode,
String transformDescription) {
// - The blank final field errorDescription may not have been
initialized
super(processDescription + " " + transformDescription);
this.processCode = processCode;
this.processDescription = processDescription;
this.transformCode = transformCode;
this.transformDescription = transformDescription;
}
public CrifServiceFaultException(String errorCode, String errorDescription) { // The blank final field transformDescription may not have been initialized
super(errorDescription);
setErrorCode(errorCode);
setErrorDescription(errorDescription);
}
final private String processCode;
final private String processDescription;
final private String transformCode;
final private String transformDescription;
final private String errorCode;
final private String errorDescription;
// getters are here
}
Because, according to Java specifications, every final variable must be initialized before the end of the constructor.
In your case in each constructor you leave some of them uninitialized (formally they're blank). In short you have to set a value for them (even when unused in a specific constructor):
public CrifServiceFaultException(String message)
{
super(message);
processCode = "";
processDescription = "";
transformCode= "";
transformDescription= "";
errorCode= "";
errorDescription= "";
}
public CrifServiceFaultException(String processCode,
String processDescription, String transformCode,
String transformDescription)
{
super(processDescription + " " + transformDescription);
this.processCode = processCode;
this.processDescription = processDescription;
this.transformCode = transformCode;
this.transformDescription = transformDescription;
errorCode= "";
errorDescription= "";
}
public CrifServiceFaultException(String errorCode, String errorDescription)
{
super(errorDescription);
setErrorCode(errorCode);
setErrorDescription(errorDescription);
processCode = "";
processDescription = "";
transformCode= "";
transformDescription= "";
}
Note that even documentation says that:
...Declaring a variable final can serve as useful documentation...
From such sentence what we can guess is that final is only a decoration useful to avoid trivial mistakes at compile time (practically pretty similar to what const is in C++). Anyway IMO we shouldn't ever assume final variables are mutable (even through JNI) because they may enable strong optimizations at run-time (I'm thinking specifically about HotSpot): think about concurrent access and cache coherency (especially for primitive types).

Generate custom Java Getters and Setters

I want to generate custom getters and setter, so I can handle variables better when I will be saving these instances into SQL database. I want to generate something like:
public class Test extends SQLEntry {
private static final String NAME = "Name";
public String getName() {
return get(NAME);
}
public void setName(String name) {
set(NAME, name);
}
}
But as I can see in Eclipse it generates only the following code:
public class Test {
private String name;
public String getName() {
return this.name;
}
public void setName(String name) {
this.name = name;
}
}
Is there some plugin, that can do it? Or am I missing something?
I have like 20 classes and I will not write this manually.
I dont know why you need this, but here is the approach to custom Getters and Setters.
You can update all generated setters and getters by going to preferences > java > Code Style > code Templates and selecting code then edit Getter body and Setter body and put this:
Getter body: return get(${field});
Setter body: set(${field}, ${param});
Let me know if that works
I recommend that instead of doing what you describe, you should use Spring Data. Specifically the BeanPropertyRowMapper class in the org.springframework.jdbc.core package will do what you want.
Read more in the Spring API documentation.
there is no other plugin available!
how can some plugin write code that is specific to your business logic!
you have to write the code manually for setters and getters in all the classes!
Try write-it-once. Template based code generator. You write custom template using Groovy, and generate file depending on java reflections. It's the simplest way to generate any file. You can make getters/settest/toString by generating AspectJ or java files, SQL based on JPA annotations, inserts / updates based on enums and so on.
On the end I found it that it is the best to do it your self...
If you like writing a code than you will enjoy this solution the most.
public class CodeGenerator {
private final static String ENCODING = "UTF-8";
private final static String FILE_NAME = "File.txt";
public static void main(String[] args) {
try {
ArrayList<Carriage> names = getNames();
for (Carriage c : names) {
createSetter(c.name, c.capitalName);
createGetter(c.name, c.capitalName);
}
} catch (FileNotFoundException ex) {
ex.printStackTrace();
}
}
private static ArrayList<Carriage> getNames() throws FileNotFoundException {
File file = new File("/");
InputStream is = CodeGenerator.class.getResourceAsStream(FILE_NAME);
Scanner s = new java.util.Scanner(is, ENCODING).useDelimiter("\\A");
String content = s.next();
String[] lines = content.split(System.getProperty("line.separator"));
ArrayList<Carriage> ret = new ArrayList<Carriage>();
for (String line : lines) {
line = line.replaceAll("\\r", "");
int firstCapitalIndex = line.indexOf("String") + 7;
int secondCapitalIndex = line.indexOf(" ", firstCapitalIndex);
int firstIndex = line.indexOf("\"") + 1;
int secondIndex = line.indexOf("\"", firstIndex + 1);
Carriage c = new Carriage();
c.name = line.substring(firstIndex, secondIndex);
c.capitalName = line.substring(firstCapitalIndex, secondCapitalIndex);
ret.add(c);
}
return ret;
}
public static void createSetter(String name, String capitalName) {
String str = "public void set" + name + "(String val) {\n"
+ "\tset(" + capitalName + ", val);\n"
+ "}\n";
System.out.println(str);
}
public static void createGetter(String name, String capitalName) {
String str = "public String get" + name + "() {\n"
+ "\treturn (String) get(" + capitalName + ");\n"
+ "}\n";
System.out.println(str);
}
carriage:
package codegenerator;
public class Carriage {
public String name;
public String capitalName;
}
And to File.txt I just coppy all defined constants and run the generator...
public static final String NAME = "Name";
public static final String PHONE = "Phone";
public static final String EMAIL = "Email";
public static final String ADDRESS_1 = "Address1";
public static final String ADDRESS_2 = "Address2";
public static final String ADDRESS_3 = "Address3";
public static final String ICO = "Ico";
public static final String DIC = "Dic";
public static final String ADMIN_LOGIN = "AdminLogin";
public static final String ADMIN_PASSWORD = "AdminPassword";
public static final String LANGUAGE = "Language";
public static final String CODE = "CODE";
public static final String MONTHLY_PAYMENT = "MonthlyPayment";

Why am I geting these bracket errors in my code?

I'm really not sure why it's doing this but it seems to be an issue with brackets.
I'm getting the following errors while running this segment of code for Android in Eclipse:
private static final String TWITTER_ACCESS_TOKEN_URL = "http://api.twitter.com/oauth/access_token";
private static final String TWITTER_AUTHORZE_URL = "https://api.twitter.com/oauth/authorize";
private static final String TWITTER_REQUEST_URL = "https://api.twitter.com/oauth/request_token";
public static final String itemOfClothing;
public static final String clothingEmotion;
public static final String user;<<<<<<<<<<<<<<<<<<<<< Syntax error on token ";", { expected after this token
itemOfClothing = "pants";
clothingEmotion = "I'm feeling left in the dark";
user = "stuart";
public static String MESSAGE = itemOfClothing +": " + clothingEmotion + "! #" + user + "EmotionalClothing"; <<<<<<<<<<<<<<<<<<<<<< Syntax error, insert "}" to complete Block
public TwitterApp(Activity context, String consumerKey, String secretKey) {
this.context = context;
You should initialize your strings at the point of declaration only, or inside a constructor. You can't have statements at the top-level class. You can just have declarations there.
So, one solution is, change the below statements: -
public static final String itemOfClothing;
public static final String clothingEmotion;
public static final String user;
/** You can't have below assignments directly under the top-level class **/
itemOfClothing = "pants";
clothingEmotion = "I'm feeling left in the dark";
user = "stuart";
to: -
public static final String itemOfClothing = "pants";
public static final String clothingEmotion = "I'm feeling left in the dark";
public static final String user = "stuart";
Or, another solution is, to move those assignments in a constructor, in which case, you would have to move the initialization of MESSAGE also in that constructor.
And also, if those variables are supposed to be constants, which I assume they are, as they are public static final, then your should use ALL_CAPS_WITH_UNDERSCORE to name them.

Categories