Featured FREE Whitepapers

What's New Here?

aspectj-logo

Implementing Active Record Pattern with Spring AOP

During class design we should take decisions about the assignment of responsibilities that will have every class. If we have chosen well, systems tend to be easier to understand, maintain and extend. Almost all of our projects have a persistence layer, either relational database, document stores, or simply XML files. And typically you will use DAO pattern to implement abstract interface between your business objects and your data store. In this post but I am going to explain another pattern that can be used instead of DAO pattern. Active record pattern is an architectural pattern that force you to implement CRUD operations on your model class, hence model class itself is responsible for saving, deleting, loading from database. There are many strategies to follow to implement this pattern, but for me, the best one is using Aspect Oriented Programming, because we are still maintaining separation of concerns favoring isolated unit testing, and not breaking encapsulation. Aspect-oriented programming entails breaking down program logic into distinct parts. These parts are known as crosscutting concerns because they “cut across” multiple abstractions in a program. Example of crosscutting concerns can be logging, transaction manager, error manager or splitting large datasets. For people that have worked with aspects not much secret here, to use them you simply create an aspect defining the advice and the pointcut, and your aspect is ready to be executed. I guess most of us use aspects-oriented programming as I have described in previous paragraph, but will be fewer that uses ITD (Inter-type Declarations) feature. Inter-type Declarations provide a way to express crosscutting concerns affecting the structure of modules enabling programmers to declare members of another class. As we say in my country “bad said but well understood“, ITD is a way to declare new components (attributes, methods, annotations) of a class from an aspect. AspectJ is an aspect-oriented extension for Java. AspectJ supports ITD, and for this reason will be used in this post. Moreover I recommend you install AJDT plugin because it will help you develop aspects and having a quick overview of which Java classes are aspecterized.If you have not understood what ITD is, don’t worry, it is a typical example of concept that is best understood with an example. Let’s start with simple example: Imagine having to model a car. You would have a car class, with some attributes, for this example three attributes (vin number, miles drived and model) is enough. public class Car {public void setVin(String vin) {this.vin = vin;} public String getVin() {return this.vin;} private String vin;public void setMileNum(int mileNum) { this.mileNum = mileNum;} public int getMileNum() {return this.mileNum;} private int mileNum;public void setModel(String model) {this.model = model;} public String getModel() {return this.model;} private String model;}It is a POJO with three attributes and their getters and setters. Now we want to add persistence layer, but in this case we are going to persist our POJOs in a XML file instead of a database. So Car objects should be transformed to XML stream. For this purpose JAXB annotations will be used. For those who don’t know, JAXB allows developers to map Java classes to XML representations and viceversa. I am sure that first idea that comes to your brain is annotating Car class with @XmlRootElement (annotation to map root element in JAXB). Don’t do that, use aspects. Your first mission is trying to maintain Car file as simple as possible. To add an annotation using ITD, is as simple as: public aspect Car_Jaxb {declare @type: Car: @XmlRootElement; }With @type you are exposing which member is annotated. In this case only class. Other possibilities are @method, @constructor and @field. Then elements pattern that should be annotated, in this case Car class, but you could use any regular expressions like org.alexsotob..*. Finally the annotation. Next step is using JAXB classes to marshalling/unmarshalling objects. In this example I am using spring-oxm package and briefly you will understand why. Spring-oxm is a part of spring-core that contains classes for dealing with O/X Mapping. This spring module contains one class for each Xml binding supported. In our case Jaxb2Marshaller is used as marshaller and unmarshaller. It is possible that you are thinking of creating a service class where you inject Jaxb2Marshaller instance. This service would include two methods (save and load) with Car class as argument or return value. Sorry but, doing this, you are implementing DAO pattern. Let’s implement Active Record pattern approach. And as you may suppose, aspectj comes to rescue you to avoid mixing concepts in same source file. Let’s update previous aspect file so all required logic by JAXB will be in same file. import java.io.IOException; import java.io.InputStream; import java.io.OutputStream;import javax.xml.bind.annotation.XmlRootElement; import javax.xml.transform.stream.StreamResult; import javax.xml.transform.stream.StreamSource;import org.springframework.beans.factory.annotation.Autowired; import org.springframework.oxm.jaxb.Jaxb2Marshaller;public aspect Car_Jaxb {declare @type: Car: @XmlRootElement;@Autowired transient Jaxb2Marshaller Car.marshaller;public void Car.save(OutputStream outputStream) throws IOException { this.marshaller.marshal(this, new StreamResult(outputStream)); }public Car Car.load(InputStream inputStream) throws IOException { return (Car)this.marshaller.unmarshal(new StreamSource(inputStream)); }}See that apart from annotating Car class we are creating two methods, and an annotated attribute. Attributes must follow same rule as methods, <class name> dot (.) and <attribute name>. Note that in this case attribute is transient because should not be bound in XML file. Last step is configuring marshaller in spring context file. <?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:oxm="http://www.springframework.org/schema/oxm" xmlns:context="http://www.springframework.org/schema/context" xsi:schemaLocation="http://www.springframework.org/schema/oxm http://www.springframework.org/schema/oxm/spring-oxm-3.0.xsd http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd"><oxm:jaxb2-marshaller id="marshaller"> <oxm:class-to-be-bound name="org.alexsotob.itd.Car"/> </oxm:jaxb2-marshaller></beans>Not much secret. Now let’s code a unit test. @RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration(locations="/context.xml") public class CarOxmBehaviour {@Test public void shouldSaveCarToXml() throws Exception { //Given Car car = new Car(); car.setMileNum(1000); car.setModel("Ferrari"); car.setVin("1M8GDM9AXKP042788"); //From http://en.wikipedia.org/wiki/Vehicle_Identification_Number//When ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(); car.save(byteArrayOutputStream);//Then String expectedMessage = "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?><car><mileNum>1000</mileNum><model>Ferrari</model><vin>1M8GDM9AXKP042788</vin></car>"; String xmlMessage = byteArrayOutputStream.toString("UTF-8");assertThat(the(xmlMessage), isEquivalentTo(the(expectedMessage))); }}Run junit class and BOOM all red, with an amazing NullPointerException. Marshaller is created in Spring context, but not injected into Car class (Car is not managed by spring container, so is impossible to be injected). And now I suppose you are telling yourself: “I told you a service layer would be better, because it would be managed by Spring and autowired would work perfect.”. But wait and see. How about using spring-aspects module? Spring Aspects contains an annotation-driven aspect (@Configurable) allowing dependency injection of any object, whatever is or not controlled by container. So let’s apply last two changes and the application will run. First of all is creating a new aspectj file to annotate Car class as Configurable. import org.springframework.beans.factory.annotation.Configurable;public aspect Car_Configurable {declare @type: Car: @Configurable;}And finally modify spring context file to allow @Configurable annotation. <?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:oxm="http://www.springframework.org/schema/oxm" xmlns:context="http://www.springframework.org/schema/context" xsi:schemaLocation="http://www.springframework.org/schema/oxm http://www.springframework.org/schema/oxm/spring-oxm-3.0.xsd http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd"><oxm:jaxb2-marshaller id="marshaller"> <oxm:class-to-be-bound name="org.alexsotob.itd.Car"/> </oxm:jaxb2-marshaller> <context:spring-configured></context:spring-configured> </beans>Adding <context:spring-configured></context:spring-configured> namespace is enough. As a result, any time you instantiate an object (via the “new” keyword), Spring will attempt to perform dependency injection on that object. Now run unit test again and green will invade your computer :D. ITD is a really nice solution to design classes with its own responsibilities. It gives you the oportunity of writing maintainable and understandable code, without loosing encapsulation. Of course you should take care of not to have high coupling in aspected classes, and convert them in “God Classes”. Note that implementing same approach but using relational database, it is as simple as changing Jaxb2Marshaller to EntityManager. I wish you have found this post useful. Download Full code Reference: Implementing Active Record Pattern with Spring AOP from our JCG partner Alex Soto at the One Jar To Rule Them All blog....
packt-logo

Free Copies of Android books Giveaway Roundup

Hello fellow Java Geeks! Our first giveaway of Packt Publishing’s best selling books on Android has ended. The Prize Winners The 3 lucky winners that will receive the ebook prizes are (names are as appeared on their emails) :Nir M Cihad Emre Mark LambertEach one of the 3 winners will recieve 2 copies (one of each ebook) of the following ebooks on Android programming for free : The Prizes 1. Android 3.0 Animations: Beginner’s GuideThe first and only book dedicated to creating animations for Android apps. Covers all of the commonly used animation techniques for Android 3.0 and lower versions. A step-by-step guide for learning animation by building fun example applications and games.Read more about this book and download free Sample Chapter 2. Android NDK Beginner’s GuideCreate high performance applications with C/C++ and integrate with Java Exploit advanced Android features such as graphics, sound, input and sensing Port and reuse your own or third-party libraries from the prolific C/C++ ecosystemRead more about this book and download free Sample Chapter Discount coupon For the rest of our readers, Packt Publishing has provided us with a discount coupon regarding the Android 3.0 Animations: Beginner’s Guide book. Codeword : Java15 15% discount on Print version. If ebook is purchased along with its corresponding print copy using the discount code provided above, the ebook is available at 85% off. Duration : 20th February 2012 up to 5th March 2012 (expiration) Happy reading/coding! The Java Code Geeks team ...
software-development-2-logo

Introduction to Strong Cryptography

One thing that amazes me is that the most developers are not familiar with strong cryptography. In my career, I’ve seen all sort of mistakes that lead to leaked data, guessable passwords, unfortunate disclosures, and worse. The nice thing is, you don’t have to understand the ridiculously complex math behind the algorithms, you only have to know the rules for using them correctly. By the end of this series, my goal is to de-mystify the magic, so you can start using the primitives in your code right away! But first, when I say Strong Cryptography, what the hell am I referring to anyway? Strong cryptography or cryptographically strong are general terms applied cryptographic systems or components that are considered highly resistant to cryptanalysis. http://en.wikipedia.org/wiki/Strong_cryptography So Strong Cryptography is not some esoteric concept you are not privy to: Strong Cryptography is simply a set of definitions and algorithms that have been reviewed by experts, secret government agencies, and third-party organizations and found to be hard to break. One thing I’ve seen repeatedly done is that developer ‘invents’ a cryptography scheme for a particular purpose. Here’s the thing, cryptography is thousands of years old. If you’ve ever ‘invented’ your own way to ‘encrypt’ data, chances are you’ve just re-invented something that has been discovered thousandsof years ago. If you want to avoid the mistakes that WEP made with wireless, Microsoft did with the XBox, or Sony made with the PS3, this blog series should help you avoid embarrassment, AND give you something impressive to say at the next cocktail party. Finally, I just wanted to mention this is actually a very personal subject that I have a long history with. I found my first need for cryptography was passing notes to my friends as we played “Spies” in the neighborhood and needed to keep the locations of our secret forts safe. Unfortunately, my single letter substitution cipher must have been broken by some whiz kid as our treehouse was destroyed that summer… After reading Alvin’s Secret Code, we then created 2-3 sets of Caesar wheels and never lost a secret fort again! Below we’ll be covering one of the most useful Strong Cryptography primitives: The Hash function. These little beasts are amazing and have a multitudes of uses! So, what is a hash function? Glad you asked, lets quote the unabated Wikipedia: A hash function is any well-defined procedure or mathematical function that converts a large, possibly variable-sized amount of data into a small datum, usually a single integer that may serve as an index to an array (cf. associative array). The values returned by a hash function are called hash values, hash codes, hash sums, checksums or simply hashes. http://en.wikipedia.org/wiki/Hash_function Sigh, Wikipedia used to have nice user-friendly definitions for common folk, since that’s not the case, let me give my own definition: A hash function takes some input bytes, then calculates a fixed value that identifies that sequence of input bytes. Sorta like a checksum… Wait, a checksum IS a hash function! Cool! -Jonathan on cryptography. A (very bad) hash function could be as simple as “divide everything by two until you have one digit left, rounding up as you go along.” We could this function ƒ (ƒ stands for ƒailure of a hash function), and so ƒ(48) = 6 or ƒ(451) = 8. A simple way to use this function ƒ is to protect a website. When a user creates an account, they choose a number as password (p). During the account creation process we calculate a new number (c = ƒ(p)) and store it for the user. We end up with (c) number, 0-9, in a database for each user. To check a supplied password (s) against the database, we simply evaluate if (c ==ƒ(s)). This hash function ƒ isn’t really very useful in the real world, as our keyspace is only 9 possibilities, it’s scales horribly, and it’s trivial to reverse engineer, but if we substitute fail function ƒ for something better, we end up with a secure system! Technical Properties of an Ideal Hash AlgorithmIt should represent a true many-to-one function. It should take an input, and produce an identity output that can be reproduced exactly every time. For every plaintext, there is exactly one hash value. For every hash value, there are infinite plaintexts.The input plaintext can be any length. Yes, but see the next point: The output hash value is always the same size, meaning it’s fixed length. So if you gave the algorithm a plaintext of 50 bytes or 765kbytes, the length of the hash value (the output) would as be say, 16 bytes. The exact length of the output depends on the algorithm design. The always produce the same hash value (output) for the same plaintext (input). So if you hash the quote, ”I go on the principle that a public debt is a public curse” you should get the value, vjPWnnLiB0BLrqUuJjtpEM5KClg= every time. This is called identifying, fingerprinting, or hashing the plaintext. A small change in the plaintext will result in a dramatic change to the hash value. So if you change to Madison’s quote to “I go on the principle that a public debt is not a public curse” the hash value is now: g+8o7vlQAGjvlst+XsOEwIzF0Qc=. Permanent and “one way”, meaning that the hashValue cannot be reversed to plaintext. Given a particular hashValue, it is extremely difficult to find a plaintext that will produce that desired hashValue. These last two points run together… Basically, our function ƒ is far from ideal. Lets say you have (p = 5). It’s very easy to calculate an input (s) that would produce (5 = ƒ(s)). You could use any of (s = { 10, 20, 40} ). An ideal function should make this extremely difficult!!!SHA1, the standard hash algorithm SHA-1 (Secure Hash Algorithm – 1) is a hash algorithm that is quite complex, and is known to be secure at the time of this writing, for most applications (the paranoid should use SHA-256 or SHA-512). We can supply any length plaintext to SHA-1 and receive a consistent 20 byte hash value in return. Here’s how to do this is Ruby: exabrial@arclight:~$ irb >> require 'base64' => true >> require 'openssl' => true >> shaBytes = Digest::SHA1.digest('Give me liberty, or give me death!') => "\367\241\266`30 \2656\214G343\266\276\204\225cB\370\r" >> puts Base64.encode64(shaBytes) 96G2YBggtTaMRxwztr6ElWNC+A0= => nil >> exitYou can use an online hash calculator to check to see if Patrick Henry’s quote was hashed correctly. Go ahead, I’ll wait… SHA-1(Base64) : 96G2YBggtTaMRxwztr6ElWNC+A0=If we make a slight change to the plaintext, lets say: “Give me liberty, or let me eat cake!“, we will get a dramatically different output: SHA-1(Base64) : M2vPzwTPc7ALM+OkiGAwCkS1DY4=Actually, just changing the case of the first character “give me liberty, or give me death!“ will produce a completely different hashValue: SHA-1(Base64) : g1UFdWJfXWfkIVz42uLLxrJv58g=Hash Algorithm Input is indeed infinte Remember how we said the input to the hash function can be infinite? How about the entire text of The Declaration of Independence (12kb)? If you upload the file to the online calculator we’ve been using, the result is still 20 bytes: SHA-1(Base64): mGnTR5dnrXrMqEMVoLKCMzWEHjU=Here’s a quick Java program to crunch the same calculation: import java.io.InputStreamReader; import java.nio.CharBuffer; import java.security.MessageDigest; import org.apache.commons.codec.binary.Base64;public class SHA1Hasher { public static void main(String[] args) throws Exception { MessageDigest md = MessageDigest.getInstance("SHA1"); InputStreamReader insr = new InputStreamReader(SHA1Hasher.class.getResourceAsStream("/usdeclar.txt")); CharBuffer charBuff = CharBuffer.allocate(16000); String plainText; byte[] hashBytes; String hashValue; insr.read(charBuff);plainText = charBuff.flip().toString(); hashBytes = md.digest(plainText.getBytes()); hashValue = Base64.encodeBase64String(hashBytes); System.out.println("SHA-1(Base64): " + hashValue); } }Real World Usage of Hash Algorithms, Scenario 1: Storing account passwords in a database in a secure manner You’ve been tasked with creating a website for the American colonial resistance. The British are abound and are randomly inspecting everyones’ databases for suspicious activity. The Founding Fathers have an unfortunate habit of choosing patriotic passwords like “I<3America”. How can mask passwords from British patrols so the secrets of who is loyal to The Crown, and who is a revolutionary is kept secret? The best thing to do is created a ‘salted password table’ like this:USERNAME PASSWORD_HASH SALTtjefferson43 HiE0AZhRWAs6Mmd7dVqppM1WtJc= WTg68cVxPIWhat we will do is store the password hash, plus some random text called a salt (to add entropy to the user’s password). So Thomas Jefferson’s original password: I<3America now becomes I<3AmericaWTg68cVxPI and is hashed permanently to: HiE0AZhRWAs6Mmd7dVqppM1WtJc=.So how do you process a login, now that the plaintext is gone? You perform the same calculation: Take the username from the login form, and lookup the salt. Then take the plaintext password from the login form and concatenated the salt from the database to reform the original string. Hash that string, and if matches the database hash, you know the correct password was supplied! Jefferson’s original patriotic password is completely masked, so those pesky Tories will never know his true allegiance! Yarr! But what if another patriot (Paul Revere) chooses the exact same password, but is caught by the British? Couldn’t the British Regulars then just infer that anyone with the same password hash is also a patriot (and be hung)? Because we added salt (entropy) to the plaintext password, we’re guaranteed to never have the same hash twice in our database. Lets say Paul Revere creates an account with the same password: I<3America, but we followed the required practice of using SecureRandom to create a new salt:USERNAME PASSWORD_HASH SALTtjefferson43 HiE0AZhRWAs6Mmd7dVqppM1WtJc= WTg68cVxPIpaulrevere1776 aktJ/0cn69Y41vssNfZDHY1CsdE= sWVUaTGa6eSo Paul Revere’s password I<3America becomes I<3AmericasWVUaTGa6e, which is hashed to: aktJ/0cn69Y41vssNfZDHY1CsdE= and stored. Later, when Paul Revere was caught and was revealed to be a patriot, Jefferson’s secret is kept safe by salting and hashing. To summarize the benefits:A database breach means your user accounts are still secure. It’s impossible to tell if two people have the same password. There are no restrictions to the length of a user’s password. Your database column can be a fixed length instead of a varchar. SHA1 was created by people who are smarter than you (and I). You can deflate your ego and leverage their brains.Sidenote: The salt column is extremely important! Never ever, store, or send, a hash without a salt! Furthermore, the salt value must be securely generated with a random generator. You must use your language’s SecureRandom generator! You’ve been warned on these two points: they are CRITICALLY important (I can’t stress this enough)!Real World Usage of Hash Algorithms, Scenario 2: Noah Webster Yes, Noah Webster was an American revolutionary: He was a member of Connecticut militia, an editor of the Federalist newspaper, the author of American copyright, among many other things. He went on later in life to write some dictionary thing, but the important part here is he was a real hard ass when it came to teaching. So say Noah Webster has hired you to write a program to test his students spelling. Because he so adamantly believed in spelling correctly, it’s important each student get 100%. Knowing this is a bit unrealistic though, he will allow the students to retake the test as many times as they want until they get 100%. The test consists of Mr. Webster dictating a small passage of text to the class and having them enter it correctly into your program. The program should tell them whether they spelled everything correctly. This will allow them to figure out the correct answer before turning in their final answer. Another important piece of American history was that Noah Webster was a closet Ruby fan; you have to write this in Ruby. This presents a problem, because the students will be running your program, you can’t just embed the correct answer in your program, or they could look at the source code. By using a hash, you can embed the hash of the correct text in the program and compare the students input to the hash. Mr. Webster begins the test by saying to his students: Before a standing army can rule, the people must be disarmed; as they are in almost every kingdom of Europe. The supreme power in America cannot enforce unjust laws by the sword; because the whole body of the people are armed, and constitute a force superior to any bands of regular troops that can be, on any pretense, raised in the United States. The correct hash is: 6+IHAAJ1i0KmoPaowU1i0xSjcO4= Knowing what you know now, can you finish the program for Mr. Webster? Post your answer in the comments! Today we’ll dive into some deeper to some Hashing topics. Also I’m taking suggestions for subjects in my posts… Last time it was US Founding Fathers, this week it’s tragedies. We learned in our last article what a hash function is and how for every input, there is exactly one corresponding output. We’re going to apply that concept to two commons situations where confidentiality is needed. Common Situation #1: A situation in Verona Lets say you have Romeo who needs to email the following message to Mercutio: “I dreamt a dream tonight.” Unfortunately for Romeo, all the ISPs in Verona are owned by the Montague family (Not much better than Comcast). Romeo doesn’t mind if the Montagues can read his message, but he certainly has an issue of they change his message. How could Romeo be sure his message was delivered without being modified by the Montague family? Well you could run the message through a hash function and attached the hash to the message. The Montagues however, could simply modify the message, and attached the new hash value. To get around that, I suppose Romeo could calculate the hash, then tell Mercutio in private what the hash value was. However, this would defeat the purpose of emailing him, since in private he could just tell Mercutio the contents of the message. Any ideas? Introducing the new MAC (not what you think) Fortunately, there is an easy solution: Message Authentication Codes or MAC. A MAC function is a ‘keyed hash function’, so you could call it a cousin of a normal hash function. In fact, MAC functions and hash functions are nearly interchangeable! In the last article, we covered the properties of a hash function. So what makes a MAC function different from a hash function?You must posses a secret key can produce a hash value. A MAC function shouldn’t reveal ‘hints’ about the secret key, even if an attacker chooses the input.Because you must posses a secret key to produce the hash value, they are often called “Keyed Hash Functions.” So lets run the quote “The lady doth protest too much, methinks” through a MAC function: private static final byte[] keybytes = new byte[] { (byte) 0xfc, (byte) 0x4f, (byte) 0xbe, (byte) 0x23, (byte) 0x59, (byte) 0xf2, (byte) 0x42, (byte) 0x37, (byte) 0x4c, (byte) 0x80, (byte) 0x44, (byte) 0x31, (byte) 0x20, (byte) 0xda, (byte) 0x20, (byte) 0x0c };public static void main(String[] args) throws Exception { Mac mac = Mac.getInstance("HMACSHA1"); Key key = new SecretKeySpec(keybytes, "HMACSHA1"); mac.init(key); byte[] hashValue = mac.doFinal("The lady doth protest too much, methinks".getBytes()); String encodedHashValue = Base64.encodeBase64String(hashValue); System.out.println(encodedHashValue); }The above program produces this output: oOUKVR5hDRh4n0H+beVO4JvMw64=If you use a different key (lets change the last byte to 0x0d) you’ll get a completely different hash: cDdJwEBm9qIni9A7QfIQ1e9G8qo=So how does apply to Romeo and Mercutio? First, they meet in private and create a secret key. Both Romeo and Mercutio will know the secret key. Next, when they want to send an email, they run the message through the MAC function and produce a signature. Finally, the recipient runs the message through the same MAC function, using the same key. It the calculated signature matches the signature on the message, they can be assured the message was not tampered with during transmission. A MAC is actually just a wrapper Take note of the following line in the above implementation: Mac mac = Mac.getInstance("HMACSHA1");You may remember from previously that SHA1 is a fairly standard hash algorithm. Well here’s the whole story: a MAC function is just a wrapper around a standard hash function. The HMAC part of HMACSHA1 is the method of wrapping. There are other MAC implementations, such as VMAC, but they are less commonly used. VMAC performs a little better than HMAC. Since HMAC and VMAC are just wrappers, you can take almost any hash function and turn them into a keyed hash function. Using SHA1?s older brothers, we can run the same quote through the program:HMACSHA256: POP9cefgoEC9pUaWXqQ8lBbW9CdMi1k3t7LXAGYl87s= HMACSHA512:ALFIpPMbphQJ7KZQHacGIFH3T2qI5AKUqaD8lDilNnjajGL29cZdp68sLeQTjDKD+cIAfZN86udfRdecGeTm0A==Common Situation #2: Revisiting storing passwords in a database Previously we decided on the following table structureUSERNAME PASSWORD_HASH SALTtjefferson43 HiE0AZhRWAs6Mmd7dVqppM1WtJc= WTg68cVxPIpaulrevere1776 aktJ/0cn69Y41vssNfZDHY1CsdE= sWVUaTGa6eLets add one additional column:USERNAME PASSWORD_HASH SALT MAC_KEYtjefferson43 RFu51fVI/0y8gmPXkjo0Op9FRHU= WTg68cVxPI KvzpFe690vsVcW1jLqQ1vg==paulrevere1776 SmZedewg1JD7kRhndEW2cRmcyGw= sWVUaTGa6e FgIpIDFi9kJgXvkp44ua4Q==So what did we do here? Instead of using straight sha-1 function to store a representation of the user’s password, we now use HMACSHA1. What does this do for you? Not much. The better question is what does it to for hackers… It makes their life extremely difficult! A MAC defends you from hackers (again, not what you’re thinking) In our original table setup, a hacker could use two forms of attacks to crack our passwords. He could use a rainbow attack, (yes it’s really called that… No I don’t know why) or a brute force attack (not to be confused with a Bruce force attack). A rainbow attack uses a multi-terrabyte database to do a reverse lookup on our hash algorithm. The database is generated ahead of time, possibly by cooperating parties and thousands of separate computers to divide up the workload. Even with the combined effort, this still takes months to generate useful tables. However, with the finished rainbow table, an attacker could lookup a hash function output to get an arbitrary input that produces the same hash as the user’s real password. Yikes! The nice thing is, using HMACSHA1 makes this infeasible for a hacker. Because we have keyed our hash algorithm differently for every user’s password, they would have to collectively regenerate the rainbow table for every individual entry, making the rainbow very very very difficult in practice! A brute force attack is related to the rainbow attack. A brute force attack tries random combinations of letters and numbers, or even common english words until it finds an input that produces the correct output. Unfortunately, HMACSHA1 provides little additional security against brute force attacks. However, because they require powerful computing systems to run, they are less common. There are only two ways to defend against brute force attacks:Enforce good polices around passwords:12 characters No english words at least 2 numbers at least 2 symbols at least 2 uppercase lettersUse SHA-512 or SHA-256 instead of SHA-1.If you’ve enjoyed this article, all that I ask if you vote me up on DZone and HackerNews. Until next time, thank you for reading! Reference: Introduction to Strong Cryptography – p0, Introduction to Strong Cryptography – p1.0 – Hash functions, US patriots & Introduction to Strong Cryptography – p1.1 – Keyed Hashing, Hash Attacks, MACs, Shakespeare from our JCG partner Jonathan Fisher at the The Code Mechanic blog....
jboss-drools-logo

JBoss Drools – Getting started

This post will be about me getting to grips with JBoss Drools. The reasoning behind it is: SAP bought out my company’s current rules engine and Drools is one alternative we will be looking into as soon as someone has the skills to get a proof of concept up. Although there seems to be a fair amount of documentation, I always find it helps having walked through examples, which is what I am going to do here.Drools on first glance can be quite daunting, it is made up of : Drools Expert (rule engine) Being a developer this is where I will begin, the actual rules and implementation of them. The other parts I’ll get to later are: Drools Guvnor (BRMS/BPMS) Drools Flow (process/workflow) Drools Fusion (event processing/temporal reasoning) Drools Planner (automated planning) So to begin. For start, I just want to get my feet wet, I download only the Eclipse plugin and the binaries Need to install the Eclipse plugin, used the update site. Unzip the binaries to a directory and withing the Eclipse plugin settings point to that directory. The eclipse plugin will allow you to create a Drools Project and that includes the “Drools Library”, but if you are using maven you need to point to the JBoss release repo for the Drools dependencies, The KnowledgeRuntimeLoggerFactory needs XStream which you can just get from the standard maven repo. Below is my POM: <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> <modelversion>4.0.0</modelVersion> <groupId>javaitzen.drools</groupId> <artifactid>LearningToDrool</artifactId> <version>0.0.1-SNAPSHOT</version> <build> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <configuration> <source>1.6</source> <target>1.6</target> </configuration> </plugin> </plugins> </build> <properties> <drools.version>5.1.1</drools.version> </properties> <repositories> <repository> <name>JBoss</name> <id>JBoss</id> <url>http://repository.jboss.org/nexus/content/groups/public-jboss/</url> </repository> </repositories> <dependencies> <dependency> <groupId>org.drools</groupId> <artifactId>drools-core</artifactId> <version>${drools.version}</version> </dependency> <dependency> <groupId>org.drools</groupId> <artifactid>drools-compiler</artifactId> <version>${drools.version}</version> </dependency> <dependency> <groupId>org.drools</groupId> <artifactId>drools-api</artifactId> <version>${drools.version}</version> </dependency> <dependency> <groupId>com.thoughtworks.xstream</groupId> <artifactId>xstream</artifactId> <version>1.3.1</version> </dependency> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.8.1</version> <scope>test</scope> </dependency> </dependencies> </project>To add a rule, on src/main/rules, Right click -> New -> Other… Drools/Rule Resource, be sure to choose the “individual rule”. This leaves you with an empty drl file: package javaitzen.drools.rules rule "A stand alone rule" when #conditions then #actions endTo understand and use the rule language, I read the Drools Documentation and the examples project. What actually took me a little to grasp, was the basic syntax and how objects were handled in the rules and I did struggle to find anything that actually explains it simply so I will give it a shot. A note on variable names.. they do not need to have the ‘$’ but it was used in the example and without it quickly gets quite confusing. Now to step through the parts of a rule: package javaitzen.drools.rules import javaitzen.drools.RoolVO rule "Basic Rule" when $vo : RoolVO( stringValue == "Learning to drool", $booleanVal : booleanValue ) eval( $booleanVal ) then System.out.println( "First Rule" ); $vo.setStringValue("Done."); endThe package, and import keyword are self explanatory, what happens after the when is not. What is happening in “$vo : RoolVO( stringValue == “Learning to drool”, $booleanVal : booleanValue )” broken down actually is: stringValue == “Learning to drool” – This is a constraint that allows us to find all RoolVO objects known to the knowledge base that have the getStringValue() value equals to “Learning to drool”. If there are multiple instances of RoolVO that comply we will run this rule more than once, these are also referred to as matched objects. You can also have multiple constraints separated by a “,”. $booleanVal : booleanValue – We are declaring a new local variable of type boolean called $booleanVal and gets it value from isBooleanValue. $vo : RoolVO – We are declaring a new local variable of type RoolVO called $vo. The next line: “eval( $booleanVal )” - Evaluates the boolean variable, this needs to evaluate to true for the ‘then’ part of the rule to be called. Then: System.out.println( “First Rule” ); – Standard sys out. $vo.setStringValue(“Done.”); - Sets the String value on the current RoolVO object that matched the constraints to Done. The main classes / interfaces needed for a basic rule execution seem to be the following: org.drools.KnowledgeBase and it’s factory org.drools.KnowledgeBaseFactory: This is the repository of all the relevant knowledge definitions; it contains rules, processes, functions, type models. org.drools.builder.KnowledgeBuilder and it’s factory org.drools.builder.KnowledgeBuilderFactory: Transforms / parses a source file (.drl, .xsl) into a KnowledgePackage that a KnowledgeBase can understand. StatefulKnowledgeSession created by the KnowledgeBase .newStatefulKnowledgeSession(); This session is used to communicate with the actual rules engine. To quote the drools JavaDocs: StatefulKnowledgeSession is the most common way to interact with a rules engine. A StatefulKnowledgeSession allows the application to establish an iterative conversation with the engine, where the reasoning process may be triggered multiple times for the same set of data. I wrote a simple test for the rule I described earlier. package javaitzen.drools; import static org.junit.Assert.assertEquals; import org.drools.KnowledgeBase; import org.drools.KnowledgeBaseFactory; import org.drools.builder.KnowledgeBuilder; import org.drools.builder.KnowledgeBuilderError; import org.drools.builder.KnowledgeBuilderErrors; import org.drools.builder.KnowledgeBuilderFactory; import org.drools.builder.ResourceType; import org.drools.io.ResourceFactory; import org.drools.logger.KnowledgeRuntimeLogger; import org.drools.logger.KnowledgeRuntimeLoggerFactory; import org.drools.runtime.StatefulKnowledgeSession; import org.junit.Before; import org.junit.Test; public class TestBasicRules { private KnowledgeBase kbase; @Before public void setup() { KnowledgeBuilder kbuilder = KnowledgeBuilderFactory.newKnowledgeBuilder(); kbuilder.add(ResourceFactory.newClassPathResource("basic.drl"), ResourceType.DRL); KnowledgeBuilderErrors errors = kbuilder.getErrors(); if (errors.size() > 0) { for (KnowledgeBuilderError error: errors) { System.err.println(error); } throw new IllegalArgumentException("Could not parse knowledge."); } kbase = KnowledgeBaseFactory.newKnowledgeBase(); kbase.addKnowledgePackages(kbuilder.getKnowledgePackages()); } @Test public void testBasic() { StatefulKnowledgeSession ksession = kbase.newStatefulKnowledgeSession(); KnowledgeRuntimeLogger logger = KnowledgeRuntimeLoggerFactory.newFileLogger(ksession, "test"); RoolVO vo = new RoolVO(); vo.setStringValue("Learning to drool"); vo.setBooleanValue(true); ksession.insert(vo); ksession.fireAllRules(); for (Object o: ksession.getObjects()) { if(o instanceof RoolVO) { assertEquals("Done.", ((RoolVO) o).getStringValue()); } } logger.close(); } }To be honest, Drools is not nearly as intuitive as Quickrules was from what I have seen in this first task. However, below, I will start looking at using the rule flows, decision table functionality as well as the guided rules:Those in partnership with the DSL (Domain Specific Language) construct hopefully do allow for more intuitive rules creation. Previously, i went through the basic syntax and requirements to get a rule developed and tested. Now to extend that, the Drools documentation is actually quite good, there is just a ton of it, so I will try to just focus on some of the main topics. First a little thing I had to do to get the rules to run from your tests using maven, the .drls are not in the classpath by default, a simple way around that was to add the following to the POM: <build> <resources> <resource> <directory>src/main/rules</directory> </resource> </resources> </build>Now more rules scenarios and usages: Collections: Querying the contents of a can be done in 2 ways, contains and memberOf, the difference is that the collection used in conjunction with memberOf must be a variable. The drl: rule "Use a Collection" when $vo : RoolVO( listValue contains "items" ) then $vo.setStringValue("Done."); logger.log(Level.INFO,"Used a collection"); endRegular Expressions: You can use a regex as a selection criteria as well with the key words Matches and Not Matches. The drl: rule "Use a Regular Expression" when $vo : RoolVO( stringValue matches "(0?[1-9]|[12][0-9]|3[01])/(0?[1-9]|1[012])/((19|20)\\d\\d)") then $vo.setStringValue("Done."); logger.log(Level.INFO,"Found the date with a regular expression dd/mm/yyyy"); endGlobal Variables: You can define global variables, they should not be used as the are sometimes in code, to pass information between methods or in this case rules. They should rather be used to provide data or services that the rules use. An example would be something like an application specific logger, or perhaps constant lookup data loaded when the application starts. The test: public class TestBasicRules { private KnowledgeBase kbase; private Logger javaLogger = Logger.getLogger("testLogger"); @Test public void testGlobal() { StatefulKnowledgeSession ksession = kbase.newStatefulKnowledgeSession(); RoolVO vo = new RoolVO(); vo.setStringValue("Global"); ksession.insert(vo); ksession.setGlobal("logger", javaLogger); ksession.fireAllRules(); checkDone(ksession); }The drl: package javaitzen.drools.rules import javaitzen.drools.RoolVO import java.util.logging.Level global java.util.logging.Logger logger; rule "Use a Global " when $vo : RoolVO( stringValue == "Global") then $vo.setStringValue("Done."); logger.log(Level.INFO,"Logging with a global"); endRule Attributes: On a rule you can specify attribute, there are a number of these. I’ll just mention a couple handy ones (quoting the official documentation): no-loop default value: false type: Boolean When the rule’s consequence modifies a fact it may cause the Rule to activate again, causing recursion. Setting no-loop to true means the attempt to create the Activation for the current set of data will be ignored. salience default value : 0 type : integer Salience is a form of priority where rules with higher salience values are given higher priority when ordered in the Activation queue. dialect default value: as specified by the package type: String possible values: “java” or “mvel” The dialect species the language to be used for any code expressions in the LHS or the RHS code block. Currently two dialects are available, Java and MVEL. While the dialect can be specified at the package level, this attribute allows the package definition to be overridden for a rule. date-effective default value: N/A type: String, containing a date and time definition A rule can only activate if the current date and time is after date-effective attribute. date-expires default value: N/A type: String, containing a date and time definition A rule cannot activate if the current date and time is after the date-expires attribute. Guided Rule: The guided rule editor seems to allow for everything you can do in code, just visually, and potentially more intuitively for those non developers. Only thing you need to do is make sure to have the objects you want to use imported in a .package in the same location as the created .brl file.Decision Tables: In my opinion the world actually runs on spreadsheets. We all like to think that it only functions because of us and our fancy applications, but truth be told the world would miss spreadsheets more than any other single application. The business people giving us our requirements understand spread sheets, some of them better than us developers and this is the biggest single bonus on decision tables. The Drools decision table at first glance did look as if it would not be as simple to hand over to business users as the Quickrules one, but it is actually split quite clearly into “code” and “data”Now to breakdown a decision table into its parts… When creating a decision table, the eclipse plugin gives you an example, I am going to work through that. C2: Keyword ruleset, just to state that this spread sheet is a ruleset (package). D2: The ruleset (package) name. Under this row you can specify the following optional keywords: Sequential – The cell to the right of this can be true or false. If true, then salience is used to ensure that rules fire from the top down. Import – The cell to the right contains a comma separated list of classes to import. Variables – The cell immediately to the right can contain global declarations which Drools supports. This is a type, followed by a variable name. (if multiple variables are needed, comma separate them). C3/D4: Notes heading and the actual notes. C5: The RuleTable keyword and name. The “RuleTable” keyword must appear on top of the first condition column. You can have multiple rule tables on a sheet, they must just be separated by a line. C6: Marks the column as a CONDITION column, G6, does this for the ACTION. You need at least one of each for a table to be valid. If there is no data in a CONDITION column, then that condition does not apply. Other column optional keywords are: PRIORITY – This states that this column’s values will set the salience DURATION – This will set the duration values for the rule row. NO-LOOP – Same as in the drl, this specifies if rule is not allowed to loop. C7: This and subsequent columns in the row, define the actual variables referenced in the rule table. C8: This and subsequent columns in the row specifies where we are getting the data from. Row 9 and Column B are just labels / headings making the data simpler to understand, all the other fields and columns before there can be hidden as not to scare the “less technical”. The table inside B9 is then were the specific rule data is defined, hopefully directly from the specification, by a non developer. I have uploaded this project to my Google code project, incase anyone wants it. I had a little issue with the decision table because I run OpenOffice at home and not Microsoft Office, the plugin expects Excel, so it leaves a ugly little red X in my project, but it opens fine outside the IDE and still compiles in maven. In the next post, i’ll have a look at the Rule Flow, and start tackling the monster that is Guvnor Reference: Learning to Drool… Part 1 & Learning to Drool… Part 2  from our JCG partner Brian Du Preez at the Zen in the art of IT blog....
ow2-asm-logo

Manipulating Java Class Files with ASM 4 – Part One : Hello World!

What is ASM: ASM is an open source java library for manipulating java byte code. So it has the same purpose as Apache BCEL. As this article assumes that the reader has some knowledge of java class file format, it is advisable to read about it in here. So how is it different from BCEL? Well firstly it allows for an event driven way to manipulate byte code eliminating the need to load the whole class in the memory just to make a small addition. Secondly, it does not have a separate class for every single instruction. Instead, it handles opcodes directly and only has constants representing each. This reduces the size of the library to a great extent. So, ASM is simply lighter and smarter. However, ASM also has a mechanism to deal with class files by loading the whole class into the memory just in case the operation is too complex to be handled through event based processing. The current stable version of ASM is 3.3. However version 4.0 RC2 is out. So, I am going to discuss that version here. Event based processing vs in memory processing: ASM supports both event driven and in memory processing. Event driven processing is lightweight, but is a little limiting. On the other hand, in memory processing is more flexible and easy to use, but it is more heavy weight. The in memory processor internally uses the event driven processor, just like the DOM XML parser internally uses the SAX XML parser. The following program demonstrates listening to class processing events. ASMHelloWorld.java package com.geekyarticles.asm;import java.io.IOException; import java.io.InputStream; import java.util.Arrays;import org.objectweb.asm.AnnotationVisitor; import org.objectweb.asm.Attribute; import org.objectweb.asm.ClassReader; import org.objectweb.asm.ClassVisitor; import org.objectweb.asm.FieldVisitor; import org.objectweb.asm.MethodVisitor; import org.objectweb.asm.Opcodes;public class ASMHelloWorld {/** * @param args * @throws IOException */ public static void main(String[] args) throws IOException { ClassVisitor cl=new ClassVisitor(Opcodes.ASM4) { /** * Called when a class is visited. This is the method called first */ @Override public void visit(int version, int access, String name, String signature, String superName, String[] interfaces) { System.out.println("Visiting class: "+name); System.out.println("Class Major Version: "+version); System.out.println("Super class: "+superName); super.visit(version, access, name, signature, superName, interfaces); } /** * Invoked only when the class being visited is an inner class */ @Override public void visitOuterClass(String owner, String name, String desc) { System.out.println("Outer class: "+owner); super.visitOuterClass(owner, name, desc); }/** *Invoked when a class level annotation is encountered */ @Override public AnnotationVisitor visitAnnotation(String desc, boolean visible) { System.out.println("Annotation: "+desc); return super.visitAnnotation(desc, visible); }/** * When a class attribute is encountered */ @Override public void visitAttribute(Attribute attr) { System.out.println("Class Attribute: "+attr.type); super.visitAttribute(attr); }/** *When an inner class is encountered */ @Override public void visitInnerClass(String name, String outerName, String innerName, int access) { System.out.println("Inner Class: "+ innerName+" defined in "+outerName); super.visitInnerClass(name, outerName, innerName, access); } /** * When a field is encountered */ @Override public FieldVisitor visitField(int access, String name, String desc, String signature, Object value) { System.out.println("Field: "+name+" "+desc+" value:"+value); return super.visitField(access, name, desc, signature, value); } @Override public void visitEnd() { System.out.println("Method ends here"); super.visitEnd(); }/** * When a method is encountered */ @Override public MethodVisitor visitMethod(int access, String name, String desc, String signature, String[] exceptions) { System.out.println("Method: "+name+" "+desc); return super.visitMethod(access, name, desc, signature, exceptions); }/** * When the optional source is encountered */ @Override public void visitSource(String source, String debug) { System.out.println("Source: "+source); super.visitSource(source, debug); } }; InputStream in=ASMHelloWorld.class.getResourceAsStream("/java/lang/String.class"); ClassReader classReader=new ClassReader(in); classReader.accept(cl, 0);}}The above program does not do anything except printing what event is reached when. At this time, we are visiting the class java.lang.String. Note that in a java class, there is an order in which things appear. For example, methods always appear after the field. The events also occur in the same order. For more information, go through the class file format discussed in here. The code itself is very straight forward, and does not need a lot of explanation. We first extend the class ClassVisitor and override the necessary methods. Then we set up a ClassReader and call its accept method passing the object of the ClassVisitor as a parameter. New in version 4: Upto version 3.3, ClassVisitor was an interface, so we had to implement all the methods. To relieve the developer from this mess, there was ClassAdapter which had no op implementations of all methods, which the developer could extend. In version 4, ClassVisitor has become a class and ClassAdapter is no longer there. Notice that some visitor methods return objects of other methods. The methods of those Visitor objects are called when the particular kind of object is traversed. The following example shows how to use a MethodVisitor to step through the method’s code. DemoClassIntructionViewer.java package com.geekyarticles.asm;import java.io.InputStream;import org.objectweb.asm.ClassReader; import org.objectweb.asm.ClassVisitor; import org.objectweb.asm.ClassWriter; import org.objectweb.asm.MethodVisitor; import org.objectweb.asm.Opcodes; import org.objectweb.asm.commons.InstructionAdapter;public class DemoClassInstructionViewer {public static class MethodPrinterVisitor extends ClassVisitor{public MethodPrinterVisitor(int api, ClassVisitor cv) { super(api, cv); } public MethodPrinterVisitor(int api) { super(api); }@Override public MethodVisitor visitMethod(int access, String name, String desc, String signature, String[] exceptions) { System.out.println("\n"+name+desc); MethodVisitor oriMv= new MethodVisitor(4) { }; //An instructionAdapter is a special MethodVisitor that //lets us process instructions easily InstructionAdapter instMv=new InstructionAdapter(oriMv){@Override public void visitInsn(int opcode) { System.out.println(opcode); super.visitInsn(opcode); } }; return instMv; }} public static void main(String[] args) throws Exception{ InputStream in=ASMHelloWorld.class.getResourceAsStream("/com/geekyarticles/asm/ASMHelloWorld.class"); ClassReader classReader=new ClassReader(in); classReader.accept(new MethodPrinterVisitor(4), 0);}}The following is the output in this case. <init>()V 177main([Ljava/lang/String;)V 89 89 3 177Note that the instructions are direct opcodes. Generating Class: Before discussing the details of generating a class, I will talk about a real cool thing that is available in ASM. Its called ASMifier. Its a class that prints the code requred to generate a given class. The following example shows how to use ASMifier. The class has got a main method and hence can be used from the command prompt. java -cp asm-all-4.0_RC2.jar org.objectweb.asm.util.ASMifier java.lang.String>>StringDump.javaAnd the following is the output. StringDump.java package asm.java.lang; import java.util.*; import org.objectweb.asm.*; import org.objectweb.asm.attrs.*; public class StringDump implements Opcodes {public static byte[] dump () throws Exception {ClassWriter cw = new ClassWriter(0); FieldVisitor fv; MethodVisitor mv; AnnotationVisitor av0;cw.visit(V1_5, ACC_PUBLIC + ACC_FINAL + ACC_SUPER, "java/lang/String", "Ljava/lang/Object;Ljava/io/Serializable;Ljava/lang/Comparable<Ljava/lang/String;>;Ljava/lang/CharSequence;", "java/lang/Object", new String[] { "java/io/Serializable", "java/lang/Comparable", "java/lang/CharSequence" });cw.visitInnerClass("java/lang/String$1", "java/lang/String", null, ACC_STATIC + ACC_SYNTHETIC);cw.visitInnerClass("java/lang/String$CaseInsensitiveComparator", "java/lang/String", "CaseInsensitiveComparator", ACC_PRIVATE + ACC_STATIC);{ fv = cw.visitField(ACC_PRIVATE + ACC_FINAL, "value", "[C", null, null); fv.visitEnd(); } { fv = cw.visitField(ACC_PRIVATE + ACC_FINAL, "offset", "I", null, null); fv.visitEnd(); } { fv = cw.visitField(ACC_PRIVATE + ACC_FINAL, "count", "I", null, null); fv.visitEnd(); } { fv = cw.visitField(ACC_PRIVATE, "hash", "I", null, null); fv.visitEnd(); } { fv = cw.visitField(ACC_PRIVATE + ACC_FINAL + ACC_STATIC, "serialVersionUID", "J", null, new Long(-6849794470754667710L)); fv.visitEnd(); } { fv = cw.visitField(ACC_PRIVATE + ACC_FINAL + ACC_STATIC, "serialPersistentFields", "[Ljava/io/ObjectStreamField;", null, null); fv.visitEnd(); } { fv = cw.visitField(ACC_PUBLIC + ACC_FINAL + ACC_STATIC, "CASE_INSENSITIVE_ORDER", "Ljava/util/Comparator;", "Ljava/util/Comparator<Ljava/lang/String;>;", null); fv.visitEnd(); } { mv = cw.visitMethod(ACC_PUBLIC, "<init>", "()V", null, null); mv.visitCode(); mv.visitVarInsn(ALOAD, 0); mv.visitMethodInsn(INVOKESPECIAL, "java/lang/Object", "<init>", "()V"); mv.visitVarInsn(ALOAD, 0); mv.visitInsn(ICONST_0); mv.visitFieldInsn(PUTFIELD, "java/lang/String", "offset", "I"); mv.visitVarInsn(ALOAD, 0); mv.visitInsn(ICONST_0); mv.visitFieldInsn(PUTFIELD, "java/lang/String", "count", "I"); mv.visitVarInsn(ALOAD, 0); mv.visitInsn(ICONST_0); mv.visitIntInsn(NEWARRAY, T_CHAR); mv.visitFieldInsn(PUTFIELD, "java/lang/String", "value", "[C"); mv.visitInsn(RETURN); mv.visitMaxs(2, 1); mv.visitEnd(); } { mv = cw.visitMethod(ACC_PUBLIC, "<init>", "(Ljava/lang/String;)V", null, null); mv.visitCode(); mv.visitVarInsn(ALOAD, 0); mv.visitMethodInsn(INVOKESPECIAL, "java/lang/Object", "<init>", "()V"); mv.visitVarInsn(ALOAD, 1); mv.visitFieldInsn(GETFIELD, "java/lang/String", "count", "I"); mv.visitVarInsn(ISTORE, 2); mv.visitVarInsn(ALOAD, 1); mv.visitFieldInsn(GETFIELD, "java/lang/String", "value", "[C"); mv.visitVarInsn(ASTORE, 3); mv.visitVarInsn(ALOAD, 3); mv.visitInsn(ARRAYLENGTH); mv.visitVarInsn(ILOAD, 2); Label l0 = new Label(); mv.visitJumpInsn(IF_ICMPLE, l0); mv.visitVarInsn(ALOAD, 1); mv.visitFieldInsn(GETFIELD, "java/lang/String", "offset", "I"); mv.visitVarInsn(ISTORE, 5); mv.visitVarInsn(ALOAD, 3); mv.visitVarInsn(ILOAD, 5); mv.visitVarInsn(ILOAD, 5); mv.visitVarInsn(ILOAD, 2); mv.visitInsn(IADD); mv.visitMethodInsn(INVOKESTATIC, "java/util/Arrays", "copyOfRange", "([CII)[C"); mv.visitVarInsn(ASTORE, 4); Label l1 = new Label(); mv.visitJumpInsn(GOTO, l1); mv.visitLabel(l0); mv.visitVarInsn(ALOAD, 3); mv.visitVarInsn(ASTORE, 4); mv.visitLabel(l1); mv.visitVarInsn(ALOAD, 0); mv.visitInsn(ICONST_0); mv.visitFieldInsn(PUTFIELD, "java/lang/String", "offset", "I"); mv.visitVarInsn(ALOAD, 0); mv.visitVarInsn(ILOAD, 2); mv.visitFieldInsn(PUTFIELD, "java/lang/String", "count", "I"); mv.visitVarInsn(ALOAD, 0); mv.visitVarInsn(ALOAD, 4); mv.visitFieldInsn(PUTFIELD, "java/lang/String", "value", "[C"); mv.visitInsn(RETURN); mv.visitMaxs(4, 6); mv.visitEnd(); } { mv = cw.visitMethod(ACC_PUBLIC, "<init>", "([C)V", null, null); mv.visitCode(); mv.visitVarInsn(ALOAD, 0); mv.visitMethodInsn(INVOKESPECIAL, "java/lang/Object", "<init>", "()V"); mv.visitVarInsn(ALOAD, 0); mv.visitInsn(ICONST_0); mv.visitFieldInsn(PUTFIELD, "java/lang/String", "offset", "I"); mv.visitVarInsn(ALOAD, 0); mv.visitVarInsn(ALOAD, 1); mv.visitInsn(ARRAYLENGTH); mv.visitFieldInsn(PUTFIELD, "java/lang/String", "count", "I"); mv.visitVarInsn(ALOAD, 0); mv.visitVarInsn(ALOAD, 1); mv.visitMethodInsn(INVOKESTATIC, "java/lang/StringValue", "from", "([C)[C"); mv.visitFieldInsn(PUTFIELD, "java/lang/String", "value", "[C"); mv.visitInsn(RETURN); mv.visitMaxs(2, 2); mv.visitEnd(); } { mv = cw.visitMethod(ACC_PUBLIC, "<init>", "([CII)V", null, null); mv.visitCode(); mv.visitVarInsn(ALOAD, 0); mv.visitMethodInsn(INVOKESPECIAL, "java/lang/Object", "<init>", "()V"); mv.visitVarInsn(ILOAD, 2); Label l0 = new Label(); mv.visitJumpInsn(IFGE, l0); mv.visitTypeInsn(NEW, "java/lang/StringIndexOutOfBoundsException"); mv.visitInsn(DUP); mv.visitVarInsn(ILOAD, 2); mv.visitMethodInsn(INVOKESPECIAL, "java/lang/StringIndexOutOfBoundsException", "<init>", "(I)V"); mv.visitInsn(ATHROW); mv.visitLabel(l0); mv.visitVarInsn(ILOAD, 3); Label l1 = new Label(); mv.visitJumpInsn(IFGE, l1); mv.visitTypeInsn(NEW, "java/lang/StringIndexOutOfBoundsException"); mv.visitInsn(DUP); mv.visitVarInsn(ILOAD, 3); mv.visitMethodInsn(INVOKESPECIAL, "java/lang/StringIndexOutOfBoundsException", "<init>", "(I)V"); mv.visitInsn(ATHROW); mv.visitLabel(l1); mv.visitVarInsn(ILOAD, 2); mv.visitVarInsn(ALOAD, 1); mv.visitInsn(ARRAYLENGTH); mv.visitVarInsn(ILOAD, 3); mv.visitInsn(ISUB); Label l2 = new Label(); mv.visitJumpInsn(IF_ICMPLE, l2); mv.visitTypeInsn(NEW, "java/lang/StringIndexOutOfBoundsException"); mv.visitInsn(DUP); mv.visitVarInsn(ILOAD, 2); mv.visitVarInsn(ILOAD, 3); mv.visitInsn(IADD); mv.visitMethodInsn(INVOKESPECIAL, "java/lang/StringIndexOutOfBoundsException", "<init>", "(I)V"); mv.visitInsn(ATHROW); mv.visitLabel(l2); mv.visitVarInsn(ALOAD, 0); mv.visitInsn(ICONST_0); mv.visitFieldInsn(PUTFIELD, "java/lang/String", "offset", "I"); mv.visitVarInsn(ALOAD, 0); mv.visitVarInsn(ILOAD, 3); mv.visitFieldInsn(PUTFIELD, "java/lang/String", "count", "I"); mv.visitVarInsn(ALOAD, 0); mv.visitVarInsn(ALOAD, 1); mv.visitVarInsn(ILOAD, 2); mv.visitVarInsn(ILOAD, 2); mv.visitVarInsn(ILOAD, 3); mv.visitInsn(IADD); mv.visitMethodInsn(INVOKESTATIC, "java/util/Arrays", "copyOfRange", "([CII)[C"); mv.visitFieldInsn(PUTFIELD, "java/lang/String", "value", "[C"); mv.visitInsn(RETURN); mv.visitMaxs(5, 4); mv.visitEnd(); } { mv = cw.visitMethod(ACC_PUBLIC, "<init>", "([III)V", null, null); mv.visitCode(); mv.visitVarInsn(ALOAD, 0); mv.visitMethodInsn(INVOKESPECIAL, "java/lang/Object", "<init>", "()V"); mv.visitVarInsn(ILOAD, 2); Label l0 = new Label(); mv.visitJumpInsn(IFGE, l0); mv.visitTypeInsn(NEW, "java/lang/StringIndexOutOfBoundsException"); mv.visitInsn(DUP); mv.visitVarInsn(ILOAD, 2); mv.visitMethodInsn(INVOKESPECIAL, "java/lang/StringIndexOutOfBoundsException", "<init>", "(I)V"); mv.visitInsn(ATHROW); mv.visitLabel(l0); mv.visitVarInsn(ILOAD, 3); Label l1 = new Label(); mv.visitJumpInsn(IFGE, l1); mv.visitTypeInsn(NEW, "java/lang/StringIndexOutOfBoundsException"); mv.visitInsn(DUP); mv.visitVarInsn(ILOAD, 3); mv.visitMethodInsn(INVOKESPECIAL, "java/lang/StringIndexOutOfBoundsException", "<init>", "(I)V"); mv.visitInsn(ATHROW); mv.visitLabel(l1); mv.visitVarInsn(ILOAD, 2); mv.visitVarInsn(ALOAD, 1); mv.visitInsn(ARRAYLENGTH); mv.visitVarInsn(ILOAD, 3); mv.visitInsn(ISUB); Label l2 = new Label(); mv.visitJumpInsn(IF_ICMPLE, l2); mv.visitTypeInsn(NEW, "java/lang/StringIndexOutOfBoundsException"); mv.visitInsn(DUP); mv.visitVarInsn(ILOAD, 2); mv.visitVarInsn(ILOAD, 3); mv.visitInsn(IADD); mv.visitMethodInsn(INVOKESPECIAL, "java/lang/StringIndexOutOfBoundsException", "<init>", "(I)V"); mv.visitInsn(ATHROW); mv.visitLabel(l2); mv.visitInsn(ICONST_0); mv.visitVarInsn(ISTORE, 4); mv.visitInsn(ICONST_1); mv.visitVarInsn(ISTORE, 5); mv.visitVarInsn(ILOAD, 3); mv.visitVarInsn(ILOAD, 5); mv.visitInsn(IADD); mv.visitIntInsn(NEWARRAY, T_CHAR); mv.visitVarInsn(ASTORE, 6); mv.visitVarInsn(ILOAD, 2); mv.visitVarInsn(ISTORE, 7); mv.visitInsn(ICONST_0); mv.visitVarInsn(ISTORE, 8); mv.visitInsn(ICONST_0); mv.visitVarInsn(ISTORE, 9); Label l3 = new Label(); mv.visitLabel(l3); mv.visitVarInsn(ILOAD, 9); mv.visitVarInsn(ILOAD, 3); Label l4 = new Label(); mv.visitJumpInsn(IF_ICMPGE, l4); mv.visitVarInsn(ALOAD, 1); mv.visitVarInsn(ILOAD, 7); mv.visitIincInsn(7, 1); mv.visitInsn(IALOAD); mv.visitVarInsn(ISTORE, 10); mv.visitVarInsn(ILOAD, 10); Label l5 = new Label(); mv.visitJumpInsn(IFGE, l5); mv.visitTypeInsn(NEW, "java/lang/IllegalArgumentException"); mv.visitInsn(DUP); mv.visitMethodInsn(INVOKESPECIAL, "java/lang/IllegalArgumentException", "<init>", "()V"); mv.visitInsn(ATHROW); mv.visitLabel(l5); mv.visitVarInsn(ILOAD, 5); Label l6 = new Label(); mv.visitJumpInsn(IFGT, l6); mv.visitVarInsn(ILOAD, 8); mv.visitInsn(ICONST_1); mv.visitInsn(IADD); mv.visitVarInsn(ALOAD, 6); mv.visitInsn(ARRAYLENGTH); mv.visitJumpInsn(IF_ICMPLT, l6); mv.visitVarInsn(ILOAD, 4); Label l7 = new Label(); mv.visitJumpInsn(IFNE, l7); mv.visitVarInsn(ILOAD, 5); mv.visitInsn(INEG); mv.visitInsn(ICONST_1); mv.visitInsn(IADD); mv.visitVarInsn(ILOAD, 3); mv.visitInsn(IMUL); mv.visitIntInsn(BIPUSH, 10); mv.visitInsn(ISHL); mv.visitVarInsn(ILOAD, 9); mv.visitInsn(IDIV); mv.visitVarInsn(ISTORE, 4); mv.visitVarInsn(ILOAD, 4); mv.visitIntInsn(BIPUSH, 10); mv.visitInsn(ISHR); mv.visitVarInsn(ISTORE, 4); mv.visitVarInsn(ILOAD, 4); Label l8 = new Label(); mv.visitJumpInsn(IFGT, l8); mv.visitInsn(ICONST_1); mv.visitVarInsn(ISTORE, 4); mv.visitJumpInsn(GOTO, l8); mv.visitLabel(l7); mv.visitVarInsn(ILOAD, 4); mv.visitInsn(ICONST_2); mv.visitInsn(IMUL); mv.visitVarInsn(ISTORE, 4); mv.visitLabel(l8); mv.visitVarInsn(ALOAD, 6); mv.visitInsn(ARRAYLENGTH); mv.visitVarInsn(ILOAD, 4); mv.visitInsn(IADD); mv.visitVarInsn(ILOAD, 3); mv.visitInsn(ICONST_2); mv.visitInsn(IMUL); mv.visitMethodInsn(INVOKESTATIC, "java/lang/Math", "min", "(II)I"); mv.visitVarInsn(ISTORE, 11); mv.visitVarInsn(ILOAD, 11); mv.visitVarInsn(ALOAD, 6); mv.visitInsn(ARRAYLENGTH); mv.visitInsn(ISUB); mv.visitVarInsn(ILOAD, 3); mv.visitVarInsn(ILOAD, 9); mv.visitInsn(ISUB); mv.visitInsn(ISUB); mv.visitVarInsn(ISTORE, 5); mv.visitVarInsn(ALOAD, 6); mv.visitVarInsn(ILOAD, 11); mv.visitMethodInsn(INVOKESTATIC, "java/util/Arrays", "copyOf", "([CI)[C"); mv.visitVarInsn(ASTORE, 6); mv.visitLabel(l6); mv.visitVarInsn(ILOAD, 10); mv.visitLdcInsn(new Integer(65536)); Label l9 = new Label(); mv.visitJumpInsn(IF_ICMPGE, l9); mv.visitVarInsn(ALOAD, 6); mv.visitVarInsn(ILOAD, 8); mv.visitIincInsn(8, 1); mv.visitVarInsn(ILOAD, 10); mv.visitInsn(I2C); mv.visitInsn(CASTORE); Label l10 = new Label(); mv.visitJumpInsn(GOTO, l10); mv.visitLabel(l9); mv.visitVarInsn(ILOAD, 10); mv.visitLdcInsn(new Integer(1114111)); Label l11 = new Label(); mv.visitJumpInsn(IF_ICMPGT, l11); mv.visitVarInsn(ILOAD, 10); mv.visitVarInsn(ALOAD, 6); mv.visitVarInsn(ILOAD, 8); mv.visitMethodInsn(INVOKESTATIC, "java/lang/Character", "toSurrogates", "(I[CI)V"); mv.visitIincInsn(8, 2); mv.visitIincInsn(5, -1); mv.visitJumpInsn(GOTO, l10); mv.visitLabel(l11); mv.visitTypeInsn(NEW, "java/lang/IllegalArgumentException"); mv.visitInsn(DUP); mv.visitMethodInsn(INVOKESPECIAL, "java/lang/IllegalArgumentException", "<init>", "()V"); mv.visitInsn(ATHROW); mv.visitLabel(l10); mv.visitIincInsn(9, 1); mv.visitJumpInsn(GOTO, l3); mv.visitLabel(l4); mv.visitVarInsn(ALOAD, 0); mv.visitInsn(ICONST_0); mv.visitFieldInsn(PUTFIELD, "java/lang/String", "offset", "I"); mv.visitVarInsn(ALOAD, 0); mv.visitVarInsn(ALOAD, 6); mv.visitFieldInsn(PUTFIELD, "java/lang/String", "value", "[C"); mv.visitVarInsn(ALOAD, 0); mv.visitVarInsn(ILOAD, 8); mv.visitFieldInsn(PUTFIELD, "java/lang/String", "count", "I"); mv.visitInsn(RETURN); mv.visitMaxs(4, 12); mv.visitEnd(); } { mv = cw.visitMethod(ACC_PUBLIC + ACC_DEPRECATED, "<init>", "([BIII)V", null, null); { av0 = mv.visitAnnotation("Ljava/lang/Deprecated;", true); av0.visitEnd(); } mv.visitCode(); mv.visitVarInsn(ALOAD, 0); mv.visitMethodInsn(INVOKESPECIAL, "java/lang/Object", "<init>", "()V"); mv.visitVarInsn(ALOAD, 1); mv.visitVarInsn(ILOAD, 3); mv.visitVarInsn(ILOAD, 4); mv.visitMethodInsn(INVOKESTATIC, "java/lang/String", "checkBounds", "([BII)V"); mv.visitVarInsn(ILOAD, 4); mv.visitIntInsn(NEWARRAY, T_CHAR); mv.visitVarInsn(ASTORE, 5); mv.visitVarInsn(ILOAD, 2); Label l0 = new Label(); mv.visitJumpInsn(IFNE, l0); mv.visitVarInsn(ILOAD, 4); mv.visitVarInsn(ISTORE, 6); Label l1 = new Label(); mv.visitLabel(l1); mv.visitVarInsn(ILOAD, 6); mv.visitIincInsn(6, -1); Label l2 = new Label(); mv.visitJumpInsn(IFLE, l2); mv.visitVarInsn(ALOAD, 5); mv.visitVarInsn(ILOAD, 6); mv.visitVarInsn(ALOAD, 1); mv.visitVarInsn(ILOAD, 6); mv.visitVarInsn(ILOAD, 3); mv.visitInsn(IADD); mv.visitInsn(BALOAD); mv.visitIntInsn(SIPUSH, 255); mv.visitInsn(IAND); mv.visitInsn(I2C); mv.visitInsn(CASTORE); mv.visitJumpInsn(GOTO, l1); mv.visitLabel(l2); Label l3 = new Label(); mv.visitJumpInsn(GOTO, l3); mv.visitLabel(l0); mv.visitVarInsn(ILOAD, 2); mv.visitIntInsn(BIPUSH, 8); mv.visitInsn(ISHL); mv.visitVarInsn(ISTORE, 2); mv.visitVarInsn(ILOAD, 4); mv.visitVarInsn(ISTORE, 6); Label l4 = new Label(); mv.visitLabel(l4); mv.visitVarInsn(ILOAD, 6); mv.visitIincInsn(6, -1); mv.visitJumpInsn(IFLE, l3); mv.visitVarInsn(ALOAD, 5); mv.visitVarInsn(ILOAD, 6); mv.visitVarInsn(ILOAD, 2); mv.visitVarInsn(ALOAD, 1); mv.visitVarInsn(ILOAD, 6); mv.visitVarInsn(ILOAD, 3); mv.visitInsn(IADD); mv.visitInsn(BALOAD); mv.visitIntInsn(SIPUSH, 255); mv.visitInsn(IAND); mv.visitInsn(IOR); mv.visitInsn(I2C); mv.visitInsn(CASTORE); mv.visitJumpInsn(GOTO, l4); mv.visitLabel(l3); mv.visitVarInsn(ALOAD, 0); mv.visitInsn(ICONST_0); mv.visitFieldInsn(PUTFIELD, "java/lang/String", "offset", "I"); mv.visitVarInsn(ALOAD, 0); mv.visitVarInsn(ILOAD, 4); mv.visitFieldInsn(PUTFIELD, "java/lang/String", "count", "I"); mv.visitVarInsn(ALOAD, 0); mv.visitVarInsn(ALOAD, 5); mv.visitFieldInsn(PUTFIELD, "java/lang/String", "value", "[C"); mv.visitInsn(RETURN); mv.visitMaxs(6, 7); mv.visitEnd(); } { mv = cw.visitMethod(ACC_PUBLIC + ACC_DEPRECATED, "<init>", "([BI)V", null, null); { av0 = mv.visitAnnotation("Ljava/lang/Deprecated;", true); av0.visitEnd(); } mv.visitCode(); mv.visitVarInsn(ALOAD, 0); mv.visitVarInsn(ALOAD, 1); mv.visitVarInsn(ILOAD, 2); mv.visitInsn(ICONST_0); mv.visitVarInsn(ALOAD, 1); mv.visitInsn(ARRAYLENGTH); mv.visitMethodInsn(INVOKESPECIAL, "java/lang/String", "<init>", "([BIII)V"); mv.visitInsn(RETURN); mv.visitMaxs(5, 3); mv.visitEnd(); } { mv = cw.visitMethod(ACC_PRIVATE + ACC_STATIC, "checkBounds", "([BII)V", null, null); mv.visitCode(); mv.visitVarInsn(ILOAD, 2); Label l0 = new Label(); mv.visitJumpInsn(IFGE, l0); mv.visitTypeInsn(NEW, "java/lang/StringIndexOutOfBoundsException"); mv.visitInsn(DUP); mv.visitVarInsn(ILOAD, 2); mv.visitMethodInsn(INVOKESPECIAL, "java/lang/StringIndexOutOfBoundsException", "<init>", "(I)V"); mv.visitInsn(ATHROW); mv.visitLabel(l0); mv.visitVarInsn(ILOAD, 1); Label l1 = new Label(); mv.visitJumpInsn(IFGE, l1); mv.visitTypeInsn(NEW, "java/lang/StringIndexOutOfBoundsException"); mv.visitInsn(DUP); mv.visitVarInsn(ILOAD, 1); mv.visitMethodInsn(INVOKESPECIAL, "java/lang/StringIndexOutOfBoundsException", "<init>", "(I)V"); mv.visitInsn(ATHROW); mv.visitLabel(l1); mv.visitVarInsn(ILOAD, 1); mv.visitVarInsn(ALOAD, 0); mv.visitInsn(ARRAYLENGTH); mv.visitVarInsn(ILOAD, 2); mv.visitInsn(ISUB); Label l2 = new Label(); mv.visitJumpInsn(IF_ICMPLE, l2); mv.visitTypeInsn(NEW, "java/lang/StringIndexOutOfBoundsException"); mv.visitInsn(DUP); mv.visitVarInsn(ILOAD, 1); mv.visitVarInsn(ILOAD, 2); mv.visitInsn(IADD); mv.visitMethodInsn(INVOKESPECIAL, "java/lang/StringIndexOutOfBoundsException", "<init>", "(I)V"); mv.visitInsn(ATHROW); mv.visitLabel(l2); mv.visitInsn(RETURN); mv.visitMaxs(4, 3); mv.visitEnd(); } { mv = cw.visitMethod(ACC_PUBLIC, "<init>", "([BIILjava/lang/String;)V", null, new String[] { "java/io/UnsupportedEncodingException" }); mv.visitCode(); mv.visitVarInsn(ALOAD, 0); mv.visitMethodInsn(INVOKESPECIAL, "java/lang/Object", "<init>", "()V"); mv.visitVarInsn(ALOAD, 4); Label l0 = new Label(); mv.visitJumpInsn(IFNONNULL, l0); mv.visitTypeInsn(NEW, "java/lang/NullPointerException"); mv.visitInsn(DUP); mv.visitLdcInsn("charsetName"); mv.visitMethodInsn(INVOKESPECIAL, "java/lang/NullPointerException", "<init>", "(Ljava/lang/String;)V"); mv.visitInsn(ATHROW); mv.visitLabel(l0); mv.visitVarInsn(ALOAD, 1); mv.visitVarInsn(ILOAD, 2); mv.visitVarInsn(ILOAD, 3); mv.visitMethodInsn(INVOKESTATIC, "java/lang/String", "checkBounds", "([BII)V"); mv.visitVarInsn(ALOAD, 4); mv.visitVarInsn(ALOAD, 1); mv.visitVarInsn(ILOAD, 2); mv.visitVarInsn(ILOAD, 3); mv.visitMethodInsn(INVOKESTATIC, "java/lang/StringCoding", "decode", "(Ljava/lang/String;[BII)[C"); mv.visitVarInsn(ASTORE, 5); mv.visitVarInsn(ALOAD, 0); mv.visitInsn(ICONST_0); mv.visitFieldInsn(PUTFIELD, "java/lang/String", "offset", "I"); mv.visitVarInsn(ALOAD, 0); mv.visitVarInsn(ALOAD, 5); mv.visitInsn(ARRAYLENGTH); mv.visitFieldInsn(PUTFIELD, "java/lang/String", "count", "I"); mv.visitVarInsn(ALOAD, 0); mv.visitVarInsn(ALOAD, 5); mv.visitFieldInsn(PUTFIELD, "java/lang/String", "value", "[C"); mv.visitInsn(RETURN); mv.visitMaxs(4, 6); mv.visitEnd(); } { mv = cw.visitMethod(ACC_PUBLIC, "<init>", "([BIILjava/nio/charset/Charset;)V", null, null); mv.visitCode(); mv.visitVarInsn(ALOAD, 0); mv.visitMethodInsn(INVOKESPECIAL, "java/lang/Object", "<init>", "()V"); mv.visitVarInsn(ALOAD, 4); Label l0 = new Label(); mv.visitJumpInsn(IFNONNULL, l0); mv.visitTypeInsn(NEW, "java/lang/NullPointerException"); mv.visitInsn(DUP); mv.visitLdcInsn("charset"); mv.visitMethodInsn(INVOKESPECIAL, "java/lang/NullPointerException", "<init>", "(Ljava/lang/String;)V"); mv.visitInsn(ATHROW); mv.visitLabel(l0); mv.visitVarInsn(ALOAD, 1); mv.visitVarInsn(ILOAD, 2); mv.visitVarInsn(ILOAD, 3); mv.visitMethodInsn(INVOKESTATIC, "java/lang/String", "checkBounds", "([BII)V"); mv.visitVarInsn(ALOAD, 4); mv.visitVarInsn(ALOAD, 1); mv.visitVarInsn(ILOAD, 2); mv.visitVarInsn(ILOAD, 3); mv.visitMethodInsn(INVOKESTATIC, "java/lang/StringCoding", "decode", "(Ljava/nio/charset/Charset;[BII)[C"); mv.visitVarInsn(ASTORE, 5); mv.visitVarInsn(ALOAD, 0); mv.visitInsn(ICONST_0); mv.visitFieldInsn(PUTFIELD, "java/lang/String", "offset", "I"); mv.visitVarInsn(ALOAD, 0); mv.visitVarInsn(ALOAD, 5); mv.visitInsn(ARRAYLENGTH); mv.visitFieldInsn(PUTFIELD, "java/lang/String", "count", "I"); mv.visitVarInsn(ALOAD, 0); mv.visitVarInsn(ALOAD, 5); mv.visitFieldInsn(PUTFIELD, "java/lang/String", "value", "[C"); mv.visitInsn(RETURN); mv.visitMaxs(4, 6); mv.visitEnd(); } { mv = cw.visitMethod(ACC_PUBLIC, "<init>", "([BLjava/lang/String;)V", null, new String[] { "java/io/UnsupportedEncodingException" }); mv.visitCode(); mv.visitVarInsn(ALOAD, 0); mv.visitVarInsn(ALOAD, 1); mv.visitInsn(ICONST_0); mv.visitVarInsn(ALOAD, 1); mv.visitInsn(ARRAYLENGTH); mv.visitVarInsn(ALOAD, 2); mv.visitMethodInsn(INVOKESPECIAL, "java/lang/String", "<init>", "([BIILjava/lang/String;)V"); mv.visitInsn(RETURN); mv.visitMaxs(5, 3); mv.visitEnd(); } { mv = cw.visitMethod(ACC_PUBLIC, "<init>", "([BLjava/nio/charset/Charset;)V", null, null); mv.visitCode(); mv.visitVarInsn(ALOAD, 0); mv.visitVarInsn(ALOAD, 1); mv.visitInsn(ICONST_0); mv.visitVarInsn(ALOAD, 1); mv.visitInsn(ARRAYLENGTH); mv.visitVarInsn(ALOAD, 2); mv.visitMethodInsn(INVOKESPECIAL, "java/lang/String", "<init>", "([BIILjava/nio/charset/Charset;)V"); mv.visitInsn(RETURN); mv.visitMaxs(5, 3); mv.visitEnd(); } { mv = cw.visitMethod(ACC_PUBLIC, "<init>", "([BII)V", null, null); mv.visitCode(); mv.visitVarInsn(ALOAD, 0); mv.visitMethodInsn(INVOKESPECIAL, "java/lang/Object", "<init>", "()V"); mv.visitVarInsn(ALOAD, 1); mv.visitVarInsn(ILOAD, 2); mv.visitVarInsn(ILOAD, 3); mv.visitMethodInsn(INVOKESTATIC, "java/lang/String", "checkBounds", "([BII)V"); mv.visitVarInsn(ALOAD, 1); mv.visitVarInsn(ILOAD, 2); mv.visitVarInsn(ILOAD, 3); mv.visitMethodInsn(INVOKESTATIC, "java/lang/StringCoding", "decode", "([BII)[C"); mv.visitVarInsn(ASTORE, 4); mv.visitVarInsn(ALOAD, 0); mv.visitInsn(ICONST_0); mv.visitFieldInsn(PUTFIELD, "java/lang/String", "offset", "I"); mv.visitVarInsn(ALOAD, 0); mv.visitVarInsn(ALOAD, 4); mv.visitInsn(ARRAYLENGTH); mv.visitFieldInsn(PUTFIELD, "java/lang/String", "count", "I"); mv.visitVarInsn(ALOAD, 0); mv.visitVarInsn(ALOAD, 4); mv.visitFieldInsn(PUTFIELD, "java/lang/String", "value", "[C"); mv.visitInsn(RETURN); mv.visitMaxs(3, 5); mv.visitEnd(); } { mv = cw.visitMethod(ACC_PUBLIC, "<init>", "([B)V", null, null); mv.visitCode(); mv.visitVarInsn(ALOAD, 0); mv.visitVarInsn(ALOAD, 1); mv.visitInsn(ICONST_0); mv.visitVarInsn(ALOAD, 1); mv.visitInsn(ARRAYLENGTH); mv.visitMethodInsn(INVOKESPECIAL, "java/lang/String", "<init>", "([BII)V"); mv.visitInsn(RETURN); mv.visitMaxs(4, 2); mv.visitEnd(); } { mv = cw.visitMethod(ACC_PUBLIC, "<init>", "(Ljava/lang/StringBuffer;)V", null, null); mv.visitCode(); mv.visitVarInsn(ALOAD, 0); mv.visitMethodInsn(INVOKESPECIAL, "java/lang/Object", "<init>", "()V"); mv.visitVarInsn(ALOAD, 1); mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/StringBuffer", "toString", "()Ljava/lang/String;"); mv.visitVarInsn(ASTORE, 2); mv.visitVarInsn(ALOAD, 0); mv.visitVarInsn(ALOAD, 2); mv.visitFieldInsn(GETFIELD, "java/lang/String", "value", "[C"); mv.visitFieldInsn(PUTFIELD, "java/lang/String", "value", "[C"); mv.visitVarInsn(ALOAD, 0); mv.visitVarInsn(ALOAD, 2); mv.visitFieldInsn(GETFIELD, "java/lang/String", "count", "I"); mv.visitFieldInsn(PUTFIELD, "java/lang/String", "count", "I"); mv.visitVarInsn(ALOAD, 0); mv.visitVarInsn(ALOAD, 2); mv.visitFieldInsn(GETFIELD, "java/lang/String", "offset", "I"); mv.visitFieldInsn(PUTFIELD, "java/lang/String", "offset", "I"); mv.visitInsn(RETURN); mv.visitMaxs(2, 3); mv.visitEnd(); } { mv = cw.visitMethod(ACC_PUBLIC, "<init>", "(Ljava/lang/StringBuilder;)V", null, null); mv.visitCode(); mv.visitVarInsn(ALOAD, 0); mv.visitMethodInsn(INVOKESPECIAL, "java/lang/Object", "<init>", "()V"); mv.visitVarInsn(ALOAD, 1); mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/StringBuilder", "toString", "()Ljava/lang/String;"); mv.visitVarInsn(ASTORE, 2); mv.visitVarInsn(ALOAD, 0); mv.visitVarInsn(ALOAD, 2); mv.visitFieldInsn(GETFIELD, "java/lang/String", "value", "[C"); mv.visitFieldInsn(PUTFIELD, "java/lang/String", "value", "[C"); mv.visitVarInsn(ALOAD, 0); mv.visitVarInsn(ALOAD, 2); mv.visitFieldInsn(GETFIELD, "java/lang/String", "count", "I"); mv.visitFieldInsn(PUTFIELD, "java/lang/String", "count", "I"); mv.visitVarInsn(ALOAD, 0); mv.visitVarInsn(ALOAD, 2); mv.visitFieldInsn(GETFIELD, "java/lang/String", "offset", "I"); mv.visitFieldInsn(PUTFIELD, "java/lang/String", "offset", "I"); mv.visitInsn(RETURN); mv.visitMaxs(2, 3); mv.visitEnd(); } { mv = cw.visitMethod(0, "<init>", "(II[C)V", null, null); mv.visitCode(); mv.visitVarInsn(ALOAD, 0); mv.visitMethodInsn(INVOKESPECIAL, "java/lang/Object", "<init>", "()V"); mv.visitVarInsn(ALOAD, 0); mv.visitVarInsn(ALOAD, 3); mv.visitFieldInsn(PUTFIELD, "java/lang/String", "value", "[C"); mv.visitVarInsn(ALOAD, 0); mv.visitVarInsn(ILOAD, 1); mv.visitFieldInsn(PUTFIELD, "java/lang/String", "offset", "I"); mv.visitVarInsn(ALOAD, 0); mv.visitVarInsn(ILOAD, 2); mv.visitFieldInsn(PUTFIELD, "java/lang/String", "count", "I"); mv.visitInsn(RETURN); mv.visitMaxs(2, 4); mv.visitEnd(); } { mv = cw.visitMethod(ACC_PUBLIC, "length", "()I", null, null); mv.visitCode(); mv.visitVarInsn(ALOAD, 0); mv.visitFieldInsn(GETFIELD, "java/lang/String", "count", "I"); mv.visitInsn(IRETURN); mv.visitMaxs(1, 1); mv.visitEnd(); } { mv = cw.visitMethod(ACC_PUBLIC, "isEmpty", "()Z", null, null); mv.visitCode(); mv.visitVarInsn(ALOAD, 0); mv.visitFieldInsn(GETFIELD, "java/lang/String", "count", "I"); Label l0 = new Label(); mv.visitJumpInsn(IFNE, l0); mv.visitInsn(ICONST_1); Label l1 = new Label(); mv.visitJumpInsn(GOTO, l1); mv.visitLabel(l0); mv.visitInsn(ICONST_0); mv.visitLabel(l1); mv.visitInsn(IRETURN); mv.visitMaxs(1, 1); mv.visitEnd(); } { mv = cw.visitMethod(ACC_PUBLIC, "charAt", "(I)C", null, null); mv.visitCode(); mv.visitVarInsn(ILOAD, 1); Label l0 = new Label(); mv.visitJumpInsn(IFLT, l0); mv.visitVarInsn(ILOAD, 1); mv.visitVarInsn(ALOAD, 0); mv.visitFieldInsn(GETFIELD, "java/lang/String", "count", "I"); Label l1 = new Label(); mv.visitJumpInsn(IF_ICMPLT, l1); mv.visitLabel(l0); mv.visitTypeInsn(NEW, "java/lang/StringIndexOutOfBoundsException"); mv.visitInsn(DUP); mv.visitVarInsn(ILOAD, 1); mv.visitMethodInsn(INVOKESPECIAL, "java/lang/StringIndexOutOfBoundsException", "<init>", "(I)V"); mv.visitInsn(ATHROW); mv.visitLabel(l1); mv.visitVarInsn(ALOAD, 0); mv.visitFieldInsn(GETFIELD, "java/lang/String", "value", "[C"); mv.visitVarInsn(ILOAD, 1); mv.visitVarInsn(ALOAD, 0); mv.visitFieldInsn(GETFIELD, "java/lang/String", "offset", "I"); mv.visitInsn(IADD); mv.visitInsn(CALOAD); mv.visitInsn(IRETURN); mv.visitMaxs(3, 2); mv.visitEnd(); } { mv = cw.visitMethod(ACC_PUBLIC, "codePointAt", "(I)I", null, null); mv.visitCode(); mv.visitVarInsn(ILOAD, 1); Label l0 = new Label(); mv.visitJumpInsn(IFLT, l0); mv.visitVarInsn(ILOAD, 1); mv.visitVarInsn(ALOAD, 0); mv.visitFieldInsn(GETFIELD, "java/lang/String", "count", "I"); Label l1 = new Label(); mv.visitJumpInsn(IF_ICMPLT, l1); mv.visitLabel(l0); mv.visitTypeInsn(NEW, "java/lang/StringIndexOutOfBoundsException"); mv.visitInsn(DUP); mv.visitVarInsn(ILOAD, 1); mv.visitMethodInsn(INVOKESPECIAL, "java/lang/StringIndexOutOfBoundsException", "<init>", "(I)V"); mv.visitInsn(ATHROW); mv.visitLabel(l1); mv.visitVarInsn(ALOAD, 0); mv.visitFieldInsn(GETFIELD, "java/lang/String", "value", "[C"); mv.visitVarInsn(ALOAD, 0); mv.visitFieldInsn(GETFIELD, "java/lang/String", "offset", "I"); mv.visitVarInsn(ILOAD, 1); mv.visitInsn(IADD); mv.visitVarInsn(ALOAD, 0); mv.visitFieldInsn(GETFIELD, "java/lang/String", "offset", "I"); mv.visitVarInsn(ALOAD, 0); mv.visitFieldInsn(GETFIELD, "java/lang/String", "count", "I"); mv.visitInsn(IADD); mv.visitMethodInsn(INVOKESTATIC, "java/lang/Character", "codePointAtImpl", "([CII)I"); mv.visitInsn(IRETURN); mv.visitMaxs(4, 2); mv.visitEnd(); } { mv = cw.visitMethod(ACC_PUBLIC, "codePointBefore", "(I)I", null, null); mv.visitCode(); mv.visitVarInsn(ILOAD, 1); mv.visitInsn(ICONST_1); mv.visitInsn(ISUB); mv.visitVarInsn(ISTORE, 2); mv.visitVarInsn(ILOAD, 2); Label l0 = new Label(); mv.visitJumpInsn(IFLT, l0); mv.visitVarInsn(ILOAD, 2); mv.visitVarInsn(ALOAD, 0); mv.visitFieldInsn(GETFIELD, "java/lang/String", "count", "I"); Label l1 = new Label(); mv.visitJumpInsn(IF_ICMPLT, l1); mv.visitLabel(l0); mv.visitTypeInsn(NEW, "java/lang/StringIndexOutOfBoundsException"); mv.visitInsn(DUP); mv.visitVarInsn(ILOAD, 1); mv.visitMethodInsn(INVOKESPECIAL, "java/lang/StringIndexOutOfBoundsException", "<init>", "(I)V"); mv.visitInsn(ATHROW); mv.visitLabel(l1); mv.visitVarInsn(ALOAD, 0); mv.visitFieldInsn(GETFIELD, "java/lang/String", "value", "[C"); mv.visitVarInsn(ALOAD, 0); mv.visitFieldInsn(GETFIELD, "java/lang/String", "offset", "I"); mv.visitVarInsn(ILOAD, 1); mv.visitInsn(IADD); mv.visitVarInsn(ALOAD, 0); mv.visitFieldInsn(GETFIELD, "java/lang/String", "offset", "I"); mv.visitMethodInsn(INVOKESTATIC, "java/lang/Character", "codePointBeforeImpl", "([CII)I"); mv.visitInsn(IRETURN); mv.visitMaxs(3, 3); mv.visitEnd(); } { mv = cw.visitMethod(ACC_PUBLIC, "codePointCount", "(II)I", null, null); mv.visitCode(); mv.visitVarInsn(ILOAD, 1); Label l0 = new Label(); mv.visitJumpInsn(IFLT, l0); mv.visitVarInsn(ILOAD, 2); mv.visitVarInsn(ALOAD, 0); mv.visitFieldInsn(GETFIELD, "java/lang/String", "count", "I"); mv.visitJumpInsn(IF_ICMPGT, l0); mv.visitVarInsn(ILOAD, 1); mv.visitVarInsn(ILOAD, 2); Label l1 = new Label(); mv.visitJumpInsn(IF_ICMPLE, l1); mv.visitLabel(l0); mv.visitTypeInsn(NEW, "java/lang/IndexOutOfBoundsException"); mv.visitInsn(DUP); mv.visitMethodInsn(INVOKESPECIAL, "java/lang/IndexOutOfBoundsException", "<init>", "()V"); mv.visitInsn(ATHROW); mv.visitLabel(l1); mv.visitVarInsn(ALOAD, 0); mv.visitFieldInsn(GETFIELD, "java/lang/String", "value", "[C"); mv.visitVarInsn(ALOAD, 0); mv.visitFieldInsn(GETFIELD, "java/lang/String", "offset", "I"); mv.visitVarInsn(ILOAD, 1); mv.visitInsn(IADD); mv.visitVarInsn(ILOAD, 2); mv.visitVarInsn(ILOAD, 1); mv.visitInsn(ISUB); mv.visitMethodInsn(INVOKESTATIC, "java/lang/Character", "codePointCountImpl", "([CII)I"); mv.visitInsn(IRETURN); mv.visitMaxs(4, 3); mv.visitEnd(); } { mv = cw.visitMethod(ACC_PUBLIC, "offsetByCodePoints", "(II)I", null, null); mv.visitCode(); mv.visitVarInsn(ILOAD, 1); Label l0 = new Label(); mv.visitJumpInsn(IFLT, l0); mv.visitVarInsn(ILOAD, 1); mv.visitVarInsn(ALOAD, 0); mv.visitFieldInsn(GETFIELD, "java/lang/String", "count", "I"); Label l1 = new Label(); mv.visitJumpInsn(IF_ICMPLE, l1); mv.visitLabel(l0); mv.visitTypeInsn(NEW, "java/lang/IndexOutOfBoundsException"); mv.visitInsn(DUP); mv.visitMethodInsn(INVOKESPECIAL, "java/lang/IndexOutOfBoundsException", "<init>", "()V"); mv.visitInsn(ATHROW); mv.visitLabel(l1); mv.visitVarInsn(ALOAD, 0); mv.visitFieldInsn(GETFIELD, "java/lang/String", "value", "[C"); mv.visitVarInsn(ALOAD, 0); mv.visitFieldInsn(GETFIELD, "java/lang/String", "offset", "I"); mv.visitVarInsn(ALOAD, 0); mv.visitFieldInsn(GETFIELD, "java/lang/String", "count", "I"); mv.visitVarInsn(ALOAD, 0); mv.visitFieldInsn(GETFIELD, "java/lang/String", "offset", "I"); mv.visitVarInsn(ILOAD, 1); mv.visitInsn(IADD); mv.visitVarInsn(ILOAD, 2); mv.visitMethodInsn(INVOKESTATIC, "java/lang/Character", "offsetByCodePointsImpl", "([CIIII)I"); mv.visitVarInsn(ALOAD, 0); mv.visitFieldInsn(GETFIELD, "java/lang/String", "offset", "I"); mv.visitInsn(ISUB); mv.visitInsn(IRETURN); mv.visitMaxs(5, 3); mv.visitEnd(); } { mv = cw.visitMethod(0, "getChars", "([CI)V", null, null); mv.visitCode(); mv.visitVarInsn(ALOAD, 0); mv.visitFieldInsn(GETFIELD, "java/lang/String", "value", "[C"); mv.visitVarInsn(ALOAD, 0); mv.visitFieldInsn(GETFIELD, "java/lang/String", "offset", "I"); mv.visitVarInsn(ALOAD, 1); mv.visitVarInsn(ILOAD, 2); mv.visitVarInsn(ALOAD, 0); mv.visitFieldInsn(GETFIELD, "java/lang/String", "count", "I"); mv.visitMethodInsn(INVOKESTATIC, "java/lang/System", "arraycopy", "(Ljava/lang/Object;ILjava/lang/Object;II)V"); mv.visitInsn(RETURN); mv.visitMaxs(5, 3); mv.visitEnd(); } { mv = cw.visitMethod(ACC_PUBLIC, "getChars", "(II[CI)V", null, null); mv.visitCode(); mv.visitVarInsn(ILOAD, 1); Label l0 = new Label(); mv.visitJumpInsn(IFGE, l0); mv.visitTypeInsn(NEW, "java/lang/StringIndexOutOfBoundsException"); mv.visitInsn(DUP); mv.visitVarInsn(ILOAD, 1); mv.visitMethodInsn(INVOKESPECIAL, "java/lang/StringIndexOutOfBoundsException", "<init>", "(I)V"); mv.visitInsn(ATHROW); mv.visitLabel(l0); mv.visitVarInsn(ILOAD, 2); mv.visitVarInsn(ALOAD, 0); mv.visitFieldInsn(GETFIELD, "java/lang/String", "count", "I"); Label l1 = new Label(); mv.visitJumpInsn(IF_ICMPLE, l1); mv.visitTypeInsn(NEW, "java/lang/StringIndexOutOfBoundsException"); mv.visitInsn(DUP); mv.visitVarInsn(ILOAD, 2); mv.visitMethodInsn(INVOKESPECIAL, "java/lang/StringIndexOutOfBoundsException", "<init>", "(I)V"); mv.visitInsn(ATHROW); mv.visitLabel(l1); mv.visitVarInsn(ILOAD, 1); mv.visitVarInsn(ILOAD, 2); Label l2 = new Label(); mv.visitJumpInsn(IF_ICMPLE, l2); mv.visitTypeInsn(NEW, "java/lang/StringIndexOutOfBoundsException"); mv.visitInsn(DUP); mv.visitVarInsn(ILOAD, 2); mv.visitVarInsn(ILOAD, 1); mv.visitInsn(ISUB); mv.visitMethodInsn(INVOKESPECIAL, "java/lang/StringIndexOutOfBoundsException", "<init>", "(I)V"); mv.visitInsn(ATHROW); mv.visitLabel(l2); mv.visitVarInsn(ALOAD, 0); mv.visitFieldInsn(GETFIELD, "java/lang/String", "value", "[C"); mv.visitVarInsn(ALOAD, 0); mv.visitFieldInsn(GETFIELD, "java/lang/String", "offset", "I"); mv.visitVarInsn(ILOAD, 1); mv.visitInsn(IADD); mv.visitVarInsn(ALOAD, 3); mv.visitVarInsn(ILOAD, 4); mv.visitVarInsn(ILOAD, 2); mv.visitVarInsn(ILOAD, 1); mv.visitInsn(ISUB); mv.visitMethodInsn(INVOKESTATIC, "java/lang/System", "arraycopy", "(Ljava/lang/Object;ILjava/lang/Object;II)V"); mv.visitInsn(RETURN); mv.visitMaxs(6, 5); mv.visitEnd(); } { mv = cw.visitMethod(ACC_PUBLIC + ACC_DEPRECATED, "getBytes", "(II[BI)V", null, null); { av0 = mv.visitAnnotation("Ljava/lang/Deprecated;", true); av0.visitEnd(); } mv.visitCode(); mv.visitVarInsn(ILOAD, 1); Label l0 = new Label(); mv.visitJumpInsn(IFGE, l0); mv.visitTypeInsn(NEW, "java/lang/StringIndexOutOfBoundsException"); mv.visitInsn(DUP); mv.visitVarInsn(ILOAD, 1); mv.visitMethodInsn(INVOKESPECIAL, "java/lang/StringIndexOutOfBoundsException", "<init>", "(I)V"); mv.visitInsn(ATHROW); mv.visitLabel(l0); mv.visitVarInsn(ILOAD, 2); mv.visitVarInsn(ALOAD, 0); mv.visitFieldInsn(GETFIELD, "java/lang/String", "count", "I"); Label l1 = new Label(); mv.visitJumpInsn(IF_ICMPLE, l1); mv.visitTypeInsn(NEW, "java/lang/StringIndexOutOfBoundsException"); mv.visitInsn(DUP); mv.visitVarInsn(ILOAD, 2); mv.visitMethodInsn(INVOKESPECIAL, "java/lang/StringIndexOutOfBoundsException", "<init>", "(I)V"); mv.visitInsn(ATHROW); mv.visitLabel(l1); mv.visitVarInsn(ILOAD, 1); mv.visitVarInsn(ILOAD, 2); Label l2 = new Label(); mv.visitJumpInsn(IF_ICMPLE, l2); mv.visitTypeInsn(NEW, "java/lang/StringIndexOutOfBoundsException"); mv.visitInsn(DUP); mv.visitVarInsn(ILOAD, 2); mv.visitVarInsn(ILOAD, 1); mv.visitInsn(ISUB); mv.visitMethodInsn(INVOKESPECIAL, "java/lang/StringIndexOutOfBoundsException", "<init>", "(I)V"); mv.visitInsn(ATHROW); mv.visitLabel(l2); mv.visitVarInsn(ILOAD, 4); mv.visitVarInsn(ISTORE, 5); mv.visitVarInsn(ALOAD, 0); mv.visitFieldInsn(GETFIELD, "java/lang/String", "offset", "I"); mv.visitVarInsn(ILOAD, 2); mv.visitInsn(IADD); mv.visitVarInsn(ISTORE, 6); mv.visitVarInsn(ALOAD, 0); mv.visitFieldInsn(GETFIELD, "java/lang/String", "offset", "I"); mv.visitVarInsn(ILOAD, 1); mv.visitInsn(IADD); mv.visitVarInsn(ISTORE, 7); mv.visitVarInsn(ALOAD, 0); mv.visitFieldInsn(GETFIELD, "java/lang/String", "value", "[C"); mv.visitVarInsn(ASTORE, 8); Label l3 = new Label(); mv.visitLabel(l3); mv.visitVarInsn(ILOAD, 7); mv.visitVarInsn(ILOAD, 6); Label l4 = new Label(); mv.visitJumpInsn(IF_ICMPGE, l4); mv.visitVarInsn(ALOAD, 3); mv.visitVarInsn(ILOAD, 5); mv.visitIincInsn(5, 1); mv.visitVarInsn(ALOAD, 8); mv.visitVarInsn(ILOAD, 7); mv.visitIincInsn(7, 1); mv.visitInsn(CALOAD); mv.visitInsn(I2B); mv.visitInsn(BASTORE); mv.visitJumpInsn(GOTO, l3); mv.visitLabel(l4); mv.visitInsn(RETURN); mv.visitMaxs(4, 9); mv.visitEnd(); } { mv = cw.visitMethod(ACC_PUBLIC, "getBytes", "(Ljava/lang/String;)[B", null, new String[] { "java/io/UnsupportedEncodingException" }); mv.visitCode(); mv.visitVarInsn(ALOAD, 1); Label l0 = new Label(); mv.visitJumpInsn(IFNONNULL, l0); mv.visitTypeInsn(NEW, "java/lang/NullPointerException"); mv.visitInsn(DUP); mv.visitMethodInsn(INVOKESPECIAL, "java/lang/NullPointerException", "<init>", "()V"); mv.visitInsn(ATHROW); mv.visitLabel(l0); mv.visitVarInsn(ALOAD, 1); mv.visitVarInsn(ALOAD, 0); mv.visitFieldInsn(GETFIELD, "java/lang/String", "value", "[C"); mv.visitVarInsn(ALOAD, 0); mv.visitFieldInsn(GETFIELD, "java/lang/String", "offset", "I"); mv.visitVarInsn(ALOAD, 0); mv.visitFieldInsn(GETFIELD, "java/lang/String", "count", "I"); mv.visitMethodInsn(INVOKESTATIC, "java/lang/StringCoding", "encode", "(Ljava/lang/String;[CII)[B"); mv.visitInsn(ARETURN); mv.visitMaxs(4, 2); mv.visitEnd(); } { mv = cw.visitMethod(ACC_PUBLIC, "getBytes", "(Ljava/nio/charset/Charset;)[B", null, null); mv.visitCode(); mv.visitVarInsn(ALOAD, 1); Label l0 = new Label(); mv.visitJumpInsn(IFNONNULL, l0); mv.visitTypeInsn(NEW, "java/lang/NullPointerException"); mv.visitInsn(DUP); mv.visitMethodInsn(INVOKESPECIAL, "java/lang/NullPointerException", "<init>", "()V"); mv.visitInsn(ATHROW); mv.visitLabel(l0); mv.visitVarInsn(ALOAD, 1); mv.visitVarInsn(ALOAD, 0); mv.visitFieldInsn(GETFIELD, "java/lang/String", "value", "[C"); mv.visitVarInsn(ALOAD, 0); mv.visitFieldInsn(GETFIELD, "java/lang/String", "offset", "I"); mv.visitVarInsn(ALOAD, 0); mv.visitFieldInsn(GETFIELD, "java/lang/String", "count", "I"); mv.visitMethodInsn(INVOKESTATIC, "java/lang/StringCoding", "encode", "(Ljava/nio/charset/Charset;[CII)[B"); mv.visitInsn(ARETURN); mv.visitMaxs(4, 2); mv.visitEnd(); } { mv = cw.visitMethod(ACC_PUBLIC, "getBytes", "()[B", null, null); mv.visitCode(); mv.visitVarInsn(ALOAD, 0); mv.visitFieldInsn(GETFIELD, "java/lang/String", "value", "[C"); mv.visitVarInsn(ALOAD, 0); mv.visitFieldInsn(GETFIELD, "java/lang/String", "offset", "I"); mv.visitVarInsn(ALOAD, 0); mv.visitFieldInsn(GETFIELD, "java/lang/String", "count", "I"); mv.visitMethodInsn(INVOKESTATIC, "java/lang/StringCoding", "encode", "([CII)[B"); mv.visitInsn(ARETURN); mv.visitMaxs(3, 1); mv.visitEnd(); } { mv = cw.visitMethod(ACC_PUBLIC, "equals", "(Ljava/lang/Object;)Z", null, null); mv.visitCode(); mv.visitVarInsn(ALOAD, 0); mv.visitVarInsn(ALOAD, 1); Label l0 = new Label(); mv.visitJumpInsn(IF_ACMPNE, l0); mv.visitInsn(ICONST_1); mv.visitInsn(IRETURN); mv.visitLabel(l0); mv.visitVarInsn(ALOAD, 1); mv.visitTypeInsn(INSTANCEOF, "java/lang/String"); Label l1 = new Label(); mv.visitJumpInsn(IFEQ, l1); mv.visitVarInsn(ALOAD, 1); mv.visitTypeInsn(CHECKCAST, "java/lang/String"); mv.visitVarInsn(ASTORE, 2); mv.visitVarInsn(ALOAD, 0); mv.visitFieldInsn(GETFIELD, "java/lang/String", "count", "I"); mv.visitVarInsn(ISTORE, 3); mv.visitVarInsn(ILOAD, 3); mv.visitVarInsn(ALOAD, 2); mv.visitFieldInsn(GETFIELD, "java/lang/String", "count", "I"); mv.visitJumpInsn(IF_ICMPNE, l1); mv.visitVarInsn(ALOAD, 0); mv.visitFieldInsn(GETFIELD, "java/lang/String", "value", "[C"); mv.visitVarInsn(ASTORE, 4); mv.visitVarInsn(ALOAD, 2); mv.visitFieldInsn(GETFIELD, "java/lang/String", "value", "[C"); mv.visitVarInsn(ASTORE, 5); mv.visitVarInsn(ALOAD, 0); mv.visitFieldInsn(GETFIELD, "java/lang/String", "offset", "I"); mv.visitVarInsn(ISTORE, 6); mv.visitVarInsn(ALOAD, 2); mv.visitFieldInsn(GETFIELD, "java/lang/String", "offset", "I"); mv.visitVarInsn(ISTORE, 7); Label l2 = new Label(); mv.visitLabel(l2); mv.visitVarInsn(ILOAD, 3); mv.visitIincInsn(3, -1); Label l3 = new Label(); mv.visitJumpInsn(IFEQ, l3); mv.visitVarInsn(ALOAD, 4); mv.visitVarInsn(ILOAD, 6); mv.visitIincInsn(6, 1); mv.visitInsn(CALOAD); mv.visitVarInsn(ALOAD, 5); mv.visitVarInsn(ILOAD, 7); mv.visitIincInsn(7, 1); mv.visitInsn(CALOAD); mv.visitJumpInsn(IF_ICMPEQ, l2); mv.visitInsn(ICONST_0); mv.visitInsn(IRETURN); mv.visitLabel(l3); mv.visitInsn(ICONST_1); mv.visitInsn(IRETURN); mv.visitLabel(l1); mv.visitInsn(ICONST_0); mv.visitInsn(IRETURN); mv.visitMaxs(3, 8); mv.visitEnd(); } { mv = cw.visitMethod(ACC_PUBLIC, "contentEquals", "(Ljava/lang/StringBuffer;)Z", null, null); mv.visitCode(); Label l0 = new Label(); Label l1 = new Label(); Label l2 = new Label(); mv.visitTryCatchBlock(l0, l1, l2, null); Label l3 = new Label(); mv.visitTryCatchBlock(l2, l3, l2, null); mv.visitVarInsn(ALOAD, 1); mv.visitInsn(DUP); mv.visitVarInsn(ASTORE, 2); mv.visitInsn(MONITORENTER); mv.visitLabel(l0); mv.visitVarInsn(ALOAD, 0); mv.visitVarInsn(ALOAD, 1); mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/String", "contentEquals", "(Ljava/lang/CharSequence;)Z"); mv.visitVarInsn(ALOAD, 2); mv.visitInsn(MONITOREXIT); mv.visitLabel(l1); mv.visitInsn(IRETURN); mv.visitLabel(l2); mv.visitVarInsn(ASTORE, 3); mv.visitVarInsn(ALOAD, 2); mv.visitInsn(MONITOREXIT); mv.visitLabel(l3); mv.visitVarInsn(ALOAD, 3); mv.visitInsn(ATHROW); mv.visitMaxs(2, 4); mv.visitEnd(); } { mv = cw.visitMethod(ACC_PUBLIC, "contentEquals", "(Ljava/lang/CharSequence;)Z", null, null); mv.visitCode(); mv.visitVarInsn(ALOAD, 0); mv.visitFieldInsn(GETFIELD, "java/lang/String", "count", "I"); mv.visitVarInsn(ALOAD, 1); mv.visitMethodInsn(INVOKEINTERFACE, "java/lang/CharSequence", "length", "()I"); Label l0 = new Label(); mv.visitJumpInsn(IF_ICMPEQ, l0); mv.visitInsn(ICONST_0); mv.visitInsn(IRETURN); mv.visitLabel(l0); mv.visitVarInsn(ALOAD, 1); mv.visitTypeInsn(INSTANCEOF, "java/lang/AbstractStringBuilder"); Label l1 = new Label(); mv.visitJumpInsn(IFEQ, l1); mv.visitVarInsn(ALOAD, 0); mv.visitFieldInsn(GETFIELD, "java/lang/String", "value", "[C"); mv.visitVarInsn(ASTORE, 2); mv.visitVarInsn(ALOAD, 1); mv.visitTypeInsn(CHECKCAST, "java/lang/AbstractStringBuilder"); mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/AbstractStringBuilder", "getValue", "()[C"); mv.visitVarInsn(ASTORE, 3); mv.visitVarInsn(ALOAD, 0); mv.visitFieldInsn(GETFIELD, "java/lang/String", "offset", "I"); mv.visitVarInsn(ISTORE, 4); mv.visitInsn(ICONST_0); mv.visitVarInsn(ISTORE, 5); mv.visitVarInsn(ALOAD, 0); mv.visitFieldInsn(GETFIELD, "java/lang/String", "count", "I"); mv.visitVarInsn(ISTORE, 6); Label l2 = new Label(); mv.visitLabel(l2); mv.visitVarInsn(ILOAD, 6); mv.visitIincInsn(6, -1); mv.visitJumpInsn(IFEQ, l1); mv.visitVarInsn(ALOAD, 2); mv.visitVarInsn(ILOAD, 4); mv.visitIincInsn(4, 1); mv.visitInsn(CALOAD); mv.visitVarInsn(ALOAD, 3); mv.visitVarInsn(ILOAD, 5); mv.visitIincInsn(5, 1); mv.visitInsn(CALOAD); mv.visitJumpInsn(IF_ICMPEQ, l2); mv.visitInsn(ICONST_0); mv.visitInsn(IRETURN); mv.visitLabel(l1); mv.visitVarInsn(ALOAD, 1); mv.visitVarInsn(ALOAD, 0); mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Object", "equals", "(Ljava/lang/Object;)Z"); Label l3 = new Label(); mv.visitJumpInsn(IFEQ, l3); mv.visitInsn(ICONST_1); mv.visitInsn(IRETURN); mv.visitLabel(l3); mv.visitVarInsn(ALOAD, 0); mv.visitFieldInsn(GETFIELD, "java/lang/String", "value", "[C"); mv.visitVarInsn(ASTORE, 2); mv.visitVarInsn(ALOAD, 0); mv.visitFieldInsn(GETFIELD, "java/lang/String", "offset", "I"); mv.visitVarInsn(ISTORE, 3); mv.visitInsn(ICONST_0); mv.visitVarInsn(ISTORE, 4); mv.visitVarInsn(ALOAD, 0); mv.visitFieldInsn(GETFIELD, "java/lang/String", "count", "I"); mv.visitVarInsn(ISTORE, 5); Label l4 = new Label(); mv.visitLabel(l4); mv.visitVarInsn(ILOAD, 5); mv.visitIincInsn(5, -1); Label l5 = new Label(); mv.visitJumpInsn(IFEQ, l5); mv.visitVarInsn(ALOAD, 2); mv.visitVarInsn(ILOAD, 3); mv.visitIincInsn(3, 1); mv.visitInsn(CALOAD); mv.visitVarInsn(ALOAD, 1); mv.visitVarInsn(ILOAD, 4); mv.visitIincInsn(4, 1); mv.visitMethodInsn(INVOKEINTERFACE, "java/lang/CharSequence", "charAt", "(I)C"); mv.visitJumpInsn(IF_ICMPEQ, l4); mv.visitInsn(ICONST_0); mv.visitInsn(IRETURN); mv.visitLabel(l5); mv.visitInsn(ICONST_1); mv.visitInsn(IRETURN); mv.visitMaxs(3, 7); mv.visitEnd(); } { mv = cw.visitMethod(ACC_PUBLIC, "equalsIgnoreCase", "(Ljava/lang/String;)Z", null, null); mv.visitCode(); mv.visitVarInsn(ALOAD, 0); mv.visitVarInsn(ALOAD, 1); Label l0 = new Label(); mv.visitJumpInsn(IF_ACMPNE, l0); mv.visitInsn(ICONST_1); Label l1 = new Label(); mv.visitJumpInsn(GOTO, l1); mv.visitLabel(l0); mv.visitVarInsn(ALOAD, 1); Label l2 = new Label(); mv.visitJumpInsn(IFNULL, l2); mv.visitVarInsn(ALOAD, 1); mv.visitFieldInsn(GETFIELD, "java/lang/String", "count", "I"); mv.visitVarInsn(ALOAD, 0); mv.visitFieldInsn(GETFIELD, "java/lang/String", "count", "I"); mv.visitJumpInsn(IF_ICMPNE, l2); mv.visitVarInsn(ALOAD, 0); mv.visitInsn(ICONST_1); mv.visitInsn(ICONST_0); mv.visitVarInsn(ALOAD, 1); mv.visitInsn(ICONST_0); mv.visitVarInsn(ALOAD, 0); mv.visitFieldInsn(GETFIELD, "java/lang/String", "count", "I"); mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/String", "regionMatches", "(ZILjava/lang/String;II)Z"); mv.visitJumpInsn(IFEQ, l2); mv.visitInsn(ICONST_1); mv.visitJumpInsn(GOTO, l1); mv.visitLabel(l2); mv.visitInsn(ICONST_0); mv.visitLabel(l1); mv.visitInsn(IRETURN); mv.visitMaxs(6, 2); mv.visitEnd(); } { mv = cw.visitMethod(ACC_PUBLIC, "compareTo", "(Ljava/lang/String;)I", null, null); mv.visitCode(); mv.visitVarInsn(ALOAD, 0); mv.visitFieldInsn(GETFIELD, "java/lang/String", "count", "I"); mv.visitVarInsn(ISTORE, 2); mv.visitVarInsn(ALOAD, 1); mv.visitFieldInsn(GETFIELD, "java/lang/String", "count", "I"); mv.visitVarInsn(ISTORE, 3); mv.visitVarInsn(ILOAD, 2); mv.visitVarInsn(ILOAD, 3); mv.visitMethodInsn(INVOKESTATIC, "java/lang/Math", "min", "(II)I"); mv.visitVarInsn(ISTORE, 4); mv.visitVarInsn(ALOAD, 0); mv.visitFieldInsn(GETFIELD, "java/lang/String", "value", "[C"); mv.visitVarInsn(ASTORE, 5); mv.visitVarInsn(ALOAD, 1); mv.visitFieldInsn(GETFIELD, "java/lang/String", "value", "[C"); mv.visitVarInsn(ASTORE, 6); mv.visitVarInsn(ALOAD, 0); mv.visitFieldInsn(GETFIELD, "java/lang/String", "offset", "I"); mv.visitVarInsn(ISTORE, 7); mv.visitVarInsn(ALOAD, 1); mv.visitFieldInsn(GETFIELD, "java/lang/String", "offset", "I"); mv.visitVarInsn(ISTORE, 8); mv.visitVarInsn(ILOAD, 7); mv.visitVarInsn(ILOAD, 8); Label l0 = new Label(); mv.visitJumpInsn(IF_ICMPNE, l0); mv.visitVarInsn(ILOAD, 7); mv.visitVarInsn(ISTORE, 9); mv.visitVarInsn(ILOAD, 4); mv.visitVarInsn(ILOAD, 7); mv.visitInsn(IADD); mv.visitVarInsn(ISTORE, 10); Label l1 = new Label(); mv.visitLabel(l1); mv.visitVarInsn(ILOAD, 9); mv.visitVarInsn(ILOAD, 10); Label l2 = new Label(); mv.visitJumpInsn(IF_ICMPGE, l2); mv.visitVarInsn(ALOAD, 5); mv.visitVarInsn(ILOAD, 9); mv.visitInsn(CALOAD); mv.visitVarInsn(ISTORE, 11); mv.visitVarInsn(ALOAD, 6); mv.visitVarInsn(ILOAD, 9); mv.visitInsn(CALOAD); mv.visitVarInsn(ISTORE, 12); mv.visitVarInsn(ILOAD, 11); mv.visitVarInsn(ILOAD, 12); Label l3 = new Label(); mv.visitJumpInsn(IF_ICMPEQ, l3); mv.visitVarInsn(ILOAD, 11); mv.visitVarInsn(ILOAD, 12); mv.visitInsn(ISUB); mv.visitInsn(IRETURN); mv.visitLabel(l3); mv.visitIincInsn(9, 1); mv.visitJumpInsn(GOTO, l1); mv.visitLabel(l2); Label l4 = new Label(); mv.visitJumpInsn(GOTO, l4); mv.visitLabel(l0); mv.visitVarInsn(ILOAD, 4); mv.visitIincInsn(4, -1); mv.visitJumpInsn(IFEQ, l4); mv.visitVarInsn(ALOAD, 5); mv.visitVarInsn(ILOAD, 7); mv.visitIincInsn(7, 1); mv.visitInsn(CALOAD); mv.visitVarInsn(ISTORE, 9); mv.visitVarInsn(ALOAD, 6); mv.visitVarInsn(ILOAD, 8); mv.visitIincInsn(8, 1); mv.visitInsn(CALOAD); mv.visitVarInsn(ISTORE, 10); mv.visitVarInsn(ILOAD, 9); mv.visitVarInsn(ILOAD, 10); Label l5 = new Label(); mv.visitJumpInsn(IF_ICMPEQ, l5); mv.visitVarInsn(ILOAD, 9); mv.visitVarInsn(ILOAD, 10); mv.visitInsn(ISUB); mv.visitInsn(IRETURN); mv.visitLabel(l5); mv.visitJumpInsn(GOTO, l0); mv.visitLabel(l4); mv.visitVarInsn(ILOAD, 2); mv.visitVarInsn(ILOAD, 3); mv.visitInsn(ISUB); mv.visitInsn(IRETURN); mv.visitMaxs(2, 13); mv.visitEnd(); } { mv = cw.visitMethod(ACC_PUBLIC, "compareToIgnoreCase", "(Ljava/lang/String;)I", null, null); mv.visitCode(); mv.visitFieldInsn(GETSTATIC, "java/lang/String", "CASE_INSENSITIVE_ORDER", "Ljava/util/Comparator;"); mv.visitVarInsn(ALOAD, 0); mv.visitVarInsn(ALOAD, 1); mv.visitMethodInsn(INVOKEINTERFACE, "java/util/Comparator", "compare", "(Ljava/lang/Object;Ljava/lang/Object;)I"); mv.visitInsn(IRETURN); mv.visitMaxs(3, 2); mv.visitEnd(); } { mv = cw.visitMethod(ACC_PUBLIC, "regionMatches", "(ILjava/lang/String;II)Z", null, null); mv.visitCode(); mv.visitVarInsn(ALOAD, 0); mv.visitFieldInsn(GETFIELD, "java/lang/String", "value", "[C"); mv.visitVarInsn(ASTORE, 5); mv.visitVarInsn(ALOAD, 0); mv.visitFieldInsn(GETFIELD, "java/lang/String", "offset", "I"); mv.visitVarInsn(ILOAD, 1); mv.visitInsn(IADD); mv.visitVarInsn(ISTORE, 6); mv.visitVarInsn(ALOAD, 2); mv.visitFieldInsn(GETFIELD, "java/lang/String", "value", "[C"); mv.visitVarInsn(ASTORE, 7); mv.visitVarInsn(ALOAD, 2); mv.visitFieldInsn(GETFIELD, "java/lang/String", "offset", "I"); mv.visitVarInsn(ILOAD, 3); mv.visitInsn(IADD); mv.visitVarInsn(ISTORE, 8); mv.visitVarInsn(ILOAD, 3); Label l0 = new Label(); mv.visitJumpInsn(IFLT, l0); mv.visitVarInsn(ILOAD, 1); mv.visitJumpInsn(IFLT, l0); mv.visitVarInsn(ILOAD, 1); mv.visitInsn(I2L); mv.visitVarInsn(ALOAD, 0); mv.visitFieldInsn(GETFIELD, "java/lang/String", "count", "I"); mv.visitInsn(I2L); mv.visitVarInsn(ILOAD, 4); mv.visitInsn(I2L); mv.visitInsn(LSUB); mv.visitInsn(LCMP); mv.visitJumpInsn(IFGT, l0); mv.visitVarInsn(ILOAD, 3); mv.visitInsn(I2L); mv.visitVarInsn(ALOAD, 2); mv.visitFieldInsn(GETFIELD, "java/lang/String", "count", "I"); mv.visitInsn(I2L); mv.visitVarInsn(ILOAD, 4); mv.visitInsn(I2L); mv.visitInsn(LSUB); mv.visitInsn(LCMP); Label l1 = new Label(); mv.visitJumpInsn(IFLE, l1); mv.visitLabel(l0); mv.visitInsn(ICONST_0); mv.visitInsn(IRETURN); mv.visitLabel(l1); mv.visitVarInsn(ILOAD, 4); mv.visitIincInsn(4, -1); Label l2 = new Label(); mv.visitJumpInsn(IFLE, l2); mv.visitVarInsn(ALOAD, 5); mv.visitVarInsn(ILOAD, 6); mv.visitIincInsn(6, 1); mv.visitInsn(CALOAD); mv.visitVarInsn(ALOAD, 7); mv.visitVarInsn(ILOAD, 8); mv.visitIincInsn(8, 1); mv.visitInsn(CALOAD); mv.visitJumpInsn(IF_ICMPEQ, l1); mv.visitInsn(ICONST_0); mv.visitInsn(IRETURN); mv.visitLabel(l2); mv.visitInsn(ICONST_1); mv.visitInsn(IRETURN); mv.visitMaxs(6, 9); mv.visitEnd(); } { mv = cw.visitMethod(ACC_PUBLIC, "regionMatches", "(ZILjava/lang/String;II)Z", null, null); mv.visitCode(); mv.visitVarInsn(ALOAD, 0); mv.visitFieldInsn(GETFIELD, "java/lang/String", "value", "[C"); mv.visitVarInsn(ASTORE, 6); mv.visitVarInsn(ALOAD, 0); mv.visitFieldInsn(GETFIELD, "java/lang/String", "offset", "I"); mv.visitVarInsn(ILOAD, 2); mv.visitInsn(IADD); mv.visitVarInsn(ISTORE, 7); mv.visitVarInsn(ALOAD, 3); mv.visitFieldInsn(GETFIELD, "java/lang/String", "value", "[C"); mv.visitVarInsn(ASTORE, 8); mv.visitVarInsn(ALOAD, 3); mv.visitFieldInsn(GETFIELD, "java/lang/String", "offset", "I"); mv.visitVarInsn(ILOAD, 4); mv.visitInsn(IADD); mv.visitVarInsn(ISTORE, 9); mv.visitVarInsn(ILOAD, 4); Label l0 = new Label(); mv.visitJumpInsn(IFLT, l0); mv.visitVarInsn(ILOAD, 2); mv.visitJumpInsn(IFLT, l0); mv.visitVarInsn(ILOAD, 2); mv.visitInsn(I2L); mv.visitVarInsn(ALOAD, 0); mv.visitFieldInsn(GETFIELD, "java/lang/String", "count", "I"); mv.visitInsn(I2L); mv.visitVarInsn(ILOAD, 5); mv.visitInsn(I2L); mv.visitInsn(LSUB); mv.visitInsn(LCMP); mv.visitJumpInsn(IFGT, l0); mv.visitVarInsn(ILOAD, 4); mv.visitInsn(I2L); mv.visitVarInsn(ALOAD, 3); mv.visitFieldInsn(GETFIELD, "java/lang/String", "count", "I"); mv.visitInsn(I2L); mv.visitVarInsn(ILOAD, 5); mv.visitInsn(I2L); mv.visitInsn(LSUB); mv.visitInsn(LCMP); Label l1 = new Label(); mv.visitJumpInsn(IFLE, l1); mv.visitLabel(l0); mv.visitInsn(ICONST_0); mv.visitInsn(IRETURN); mv.visitLabel(l1); mv.visitVarInsn(ILOAD, 5); mv.visitIincInsn(5, -1); Label l2 = new Label(); mv.visitJumpInsn(IFLE, l2); mv.visitVarInsn(ALOAD, 6); mv.visitVarInsn(ILOAD, 7); mv.visitIincInsn(7, 1); mv.visitInsn(CALOAD); mv.visitVarInsn(ISTORE, 10); mv.visitVarInsn(ALOAD, 8); mv.visitVarInsn(ILOAD, 9); mv.visitIincInsn(9, 1); mv.visitInsn(CALOAD); mv.visitVarInsn(ISTORE, 11); mv.visitVarInsn(ILOAD, 10); mv.visitVarInsn(ILOAD, 11); Label l3 = new Label(); mv.visitJumpInsn(IF_ICMPNE, l3); mv.visitJumpInsn(GOTO, l1); mv.visitLabel(l3); mv.visitVarInsn(ILOAD, 1); Label l4 = new Label(); mv.visitJumpInsn(IFEQ, l4); mv.visitVarInsn(ILOAD, 10); mv.visitMethodInsn(INVOKESTATIC, "java/lang/Character", "toUpperCase", "(C)C"); mv.visitVarInsn(ISTORE, 12); mv.visitVarInsn(ILOAD, 11); mv.visitMethodInsn(INVOKESTATIC, "java/lang/Character", "toUpperCase", "(C)C"); mv.visitVarInsn(ISTORE, 13); mv.visitVarInsn(ILOAD, 12); mv.visitVarInsn(ILOAD, 13); Label l5 = new Label(); mv.visitJumpInsn(IF_ICMPNE, l5); mv.visitJumpInsn(GOTO, l1); mv.visitLabel(l5); mv.visitVarInsn(ILOAD, 12); mv.visitMethodInsn(INVOKESTATIC, "java/lang/Character", "toLowerCase", "(C)C"); mv.visitVarInsn(ILOAD, 13); mv.visitMethodInsn(INVOKESTATIC, "java/lang/Character", "toLowerCase", "(C)C"); mv.visitJumpInsn(IF_ICMPNE, l4); mv.visitJumpInsn(GOTO, l1); mv.visitLabel(l4); mv.visitInsn(ICONST_0); mv.visitInsn(IRETURN); mv.visitLabel(l2); mv.visitInsn(ICONST_1); mv.visitInsn(IRETURN); mv.visitMaxs(6, 14); mv.visitEnd(); } { mv = cw.visitMethod(ACC_PUBLIC, "startsWith", "(Ljava/lang/String;I)Z", null, null); mv.visitCode(); mv.visitVarInsn(ALOAD, 0); mv.visitFieldInsn(GETFIELD, "java/lang/String", "value", "[C"); mv.visitVarInsn(ASTORE, 3); mv.visitVarInsn(ALOAD, 0); mv.visitFieldInsn(GETFIELD, "java/lang/String", "offset", "I"); mv.visitVarInsn(ILOAD, 2); mv.visitInsn(IADD); mv.visitVarInsn(ISTORE, 4); mv.visitVarInsn(ALOAD, 1); mv.visitFieldInsn(GETFIELD, "java/lang/String", "value", "[C"); mv.visitVarInsn(ASTORE, 5); mv.visitVarInsn(ALOAD, 1); mv.visitFieldInsn(GETFIELD, "java/lang/String", "offset", "I"); mv.visitVarInsn(ISTORE, 6); mv.visitVarInsn(ALOAD, 1); mv.visitFieldInsn(GETFIELD, "java/lang/String", "count", "I"); mv.visitVarInsn(ISTORE, 7); mv.visitVarInsn(ILOAD, 2); Label l0 = new Label(); mv.visitJumpInsn(IFLT, l0); mv.visitVarInsn(ILOAD, 2); mv.visitVarInsn(ALOAD, 0); mv.visitFieldInsn(GETFIELD, "java/lang/String", "count", "I"); mv.visitVarInsn(ILOAD, 7); mv.visitInsn(ISUB); Label l1 = new Label(); mv.visitJumpInsn(IF_ICMPLE, l1); mv.visitLabel(l0); mv.visitInsn(ICONST_0); mv.visitInsn(IRETURN); mv.visitLabel(l1); mv.visitIincInsn(7, -1); mv.visitVarInsn(ILOAD, 7); Label l2 = new Label(); mv.visitJumpInsn(IFLT, l2); mv.visitVarInsn(ALOAD, 3); mv.visitVarInsn(ILOAD, 4); mv.visitIincInsn(4, 1); mv.visitInsn(CALOAD); mv.visitVarInsn(ALOAD, 5); mv.visitVarInsn(ILOAD, 6); mv.visitIincInsn(6, 1); mv.visitInsn(CALOAD); mv.visitJumpInsn(IF_ICMPEQ, l1); mv.visitInsn(ICONST_0); mv.visitInsn(IRETURN); mv.visitLabel(l2); mv.visitInsn(ICONST_1); mv.visitInsn(IRETURN); mv.visitMaxs(3, 8); mv.visitEnd(); } { mv = cw.visitMethod(ACC_PUBLIC, "startsWith", "(Ljava/lang/String;)Z", null, null); mv.visitCode(); mv.visitVarInsn(ALOAD, 0); mv.visitVarInsn(ALOAD, 1); mv.visitInsn(ICONST_0); mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/String", "startsWith", "(Ljava/lang/String;I)Z"); mv.visitInsn(IRETURN); mv.visitMaxs(3, 2); mv.visitEnd(); } { mv = cw.visitMethod(ACC_PUBLIC, "endsWith", "(Ljava/lang/String;)Z", null, null); mv.visitCode(); mv.visitVarInsn(ALOAD, 0); mv.visitVarInsn(ALOAD, 1); mv.visitVarInsn(ALOAD, 0); mv.visitFieldInsn(GETFIELD, "java/lang/String", "count", "I"); mv.visitVarInsn(ALOAD, 1); mv.visitFieldInsn(GETFIELD, "java/lang/String", "count", "I"); mv.visitInsn(ISUB); mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/String", "startsWith", "(Ljava/lang/String;I)Z"); mv.visitInsn(IRETURN); mv.visitMaxs(4, 2); mv.visitEnd(); } { mv = cw.visitMethod(ACC_PUBLIC, "hashCode", "()I", null, null); mv.visitCode(); mv.visitVarInsn(ALOAD, 0); mv.visitFieldInsn(GETFIELD, "java/lang/String", "hash", "I"); mv.visitVarInsn(ISTORE, 1); mv.visitVarInsn(ALOAD, 0); mv.visitFieldInsn(GETFIELD, "java/lang/String", "count", "I"); mv.visitVarInsn(ISTORE, 2); mv.visitVarInsn(ILOAD, 1); Label l0 = new Label(); mv.visitJumpInsn(IFNE, l0); mv.visitVarInsn(ILOAD, 2); mv.visitJumpInsn(IFLE, l0); mv.visitVarInsn(ALOAD, 0); mv.visitFieldInsn(GETFIELD, "java/lang/String", "offset", "I"); mv.visitVarInsn(ISTORE, 3); mv.visitVarInsn(ALOAD, 0); mv.visitFieldInsn(GETFIELD, "java/lang/String", "value", "[C"); mv.visitVarInsn(ASTORE, 4); mv.visitInsn(ICONST_0); mv.visitVarInsn(ISTORE, 5); Label l1 = new Label(); mv.visitLabel(l1); mv.visitVarInsn(ILOAD, 5); mv.visitVarInsn(ILOAD, 2); Label l2 = new Label(); mv.visitJumpInsn(IF_ICMPGE, l2); mv.visitIntInsn(BIPUSH, 31); mv.visitVarInsn(ILOAD, 1); mv.visitInsn(IMUL); mv.visitVarInsn(ALOAD, 4); mv.visitVarInsn(ILOAD, 3); mv.visitIincInsn(3, 1); mv.visitInsn(CALOAD); mv.visitInsn(IADD); mv.visitVarInsn(ISTORE, 1); mv.visitIincInsn(5, 1); mv.visitJumpInsn(GOTO, l1); mv.visitLabel(l2); mv.visitVarInsn(ALOAD, 0); mv.visitVarInsn(ILOAD, 1); mv.visitFieldInsn(PUTFIELD, "java/lang/String", "hash", "I"); mv.visitLabel(l0); mv.visitVarInsn(ILOAD, 1); mv.visitInsn(IRETURN); mv.visitMaxs(3, 6); mv.visitEnd(); } { mv = cw.visitMethod(ACC_PUBLIC, "indexOf", "(I)I", null, null); mv.visitCode(); mv.visitVarInsn(ALOAD, 0); mv.visitVarInsn(ILOAD, 1); mv.visitInsn(ICONST_0); mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/String", "indexOf", "(II)I"); mv.visitInsn(IRETURN); mv.visitMaxs(3, 2); mv.visitEnd(); } { mv = cw.visitMethod(ACC_PUBLIC, "indexOf", "(II)I", null, null); mv.visitCode(); mv.visitVarInsn(ALOAD, 0); mv.visitFieldInsn(GETFIELD, "java/lang/String", "offset", "I"); mv.visitVarInsn(ALOAD, 0); mv.visitFieldInsn(GETFIELD, "java/lang/String", "count", "I"); mv.visitInsn(IADD); mv.visitVarInsn(ISTORE, 3); mv.visitVarInsn(ALOAD, 0); mv.visitFieldInsn(GETFIELD, "java/lang/String", "value", "[C"); mv.visitVarInsn(ASTORE, 4); mv.visitVarInsn(ILOAD, 2); Label l0 = new Label(); mv.visitJumpInsn(IFGE, l0); mv.visitInsn(ICONST_0); mv.visitVarInsn(ISTORE, 2); Label l1 = new Label(); mv.visitJumpInsn(GOTO, l1); mv.visitLabel(l0); mv.visitVarInsn(ILOAD, 2); mv.visitVarInsn(ALOAD, 0); mv.visitFieldInsn(GETFIELD, "java/lang/String", "count", "I"); mv.visitJumpInsn(IF_ICMPLT, l1); mv.visitInsn(ICONST_M1); mv.visitInsn(IRETURN); mv.visitLabel(l1); mv.visitVarInsn(ALOAD, 0); mv.visitFieldInsn(GETFIELD, "java/lang/String", "offset", "I"); mv.visitVarInsn(ILOAD, 2); mv.visitInsn(IADD); mv.visitVarInsn(ISTORE, 5); mv.visitVarInsn(ILOAD, 1); mv.visitLdcInsn(new Integer(65536)); Label l2 = new Label(); mv.visitJumpInsn(IF_ICMPGE, l2); Label l3 = new Label(); mv.visitLabel(l3); mv.visitVarInsn(ILOAD, 5); mv.visitVarInsn(ILOAD, 3); Label l4 = new Label(); mv.visitJumpInsn(IF_ICMPGE, l4); mv.visitVarInsn(ALOAD, 4); mv.visitVarInsn(ILOAD, 5); mv.visitInsn(CALOAD); mv.visitVarInsn(ILOAD, 1); Label l5 = new Label(); mv.visitJumpInsn(IF_ICMPNE, l5); mv.visitVarInsn(ILOAD, 5); mv.visitVarInsn(ALOAD, 0); mv.visitFieldInsn(GETFIELD, "java/lang/String", "offset", "I"); mv.visitInsn(ISUB); mv.visitInsn(IRETURN); mv.visitLabel(l5); mv.visitIincInsn(5, 1); mv.visitJumpInsn(GOTO, l3); mv.visitLabel(l4); mv.visitInsn(ICONST_M1); mv.visitInsn(IRETURN); mv.visitLabel(l2); mv.visitVarInsn(ILOAD, 1); mv.visitLdcInsn(new Integer(1114111)); Label l6 = new Label(); mv.visitJumpInsn(IF_ICMPGT, l6); mv.visitVarInsn(ILOAD, 1); mv.visitMethodInsn(INVOKESTATIC, "java/lang/Character", "toChars", "(I)[C"); mv.visitVarInsn(ASTORE, 6); Label l7 = new Label(); mv.visitLabel(l7); mv.visitVarInsn(ILOAD, 5); mv.visitVarInsn(ILOAD, 3); mv.visitJumpInsn(IF_ICMPGE, l6); mv.visitVarInsn(ALOAD, 4); mv.visitVarInsn(ILOAD, 5); mv.visitInsn(CALOAD); mv.visitVarInsn(ALOAD, 6); mv.visitInsn(ICONST_0); mv.visitInsn(CALOAD); Label l8 = new Label(); mv.visitJumpInsn(IF_ICMPNE, l8); mv.visitVarInsn(ILOAD, 5); mv.visitInsn(ICONST_1); mv.visitInsn(IADD); mv.visitVarInsn(ILOAD, 3); Label l9 = new Label(); mv.visitJumpInsn(IF_ICMPNE, l9); mv.visitJumpInsn(GOTO, l6); mv.visitLabel(l9); mv.visitVarInsn(ALOAD, 4); mv.visitVarInsn(ILOAD, 5); mv.visitInsn(ICONST_1); mv.visitInsn(IADD); mv.visitInsn(CALOAD); mv.visitVarInsn(ALOAD, 6); mv.visitInsn(ICONST_1); mv.visitInsn(CALOAD); mv.visitJumpInsn(IF_ICMPNE, l8); mv.visitVarInsn(ILOAD, 5); mv.visitVarInsn(ALOAD, 0); mv.visitFieldInsn(GETFIELD, "java/lang/String", "offset", "I"); mv.visitInsn(ISUB); mv.visitInsn(IRETURN); mv.visitLabel(l8); mv.visitIincInsn(5, 1); mv.visitJumpInsn(GOTO, l7); mv.visitLabel(l6); mv.visitInsn(ICONST_M1); mv.visitInsn(IRETURN); mv.visitMaxs(3, 7); mv.visitEnd(); } { mv = cw.visitMethod(ACC_PUBLIC, "lastIndexOf", "(I)I", null, null); mv.visitCode(); mv.visitVarInsn(ALOAD, 0); mv.visitVarInsn(ILOAD, 1); mv.visitVarInsn(ALOAD, 0); mv.visitFieldInsn(GETFIELD, "java/lang/String", "count", "I"); mv.visitInsn(ICONST_1); mv.visitInsn(ISUB); mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/String", "lastIndexOf", "(II)I"); mv.visitInsn(IRETURN); mv.visitMaxs(4, 2); mv.visitEnd(); } { mv = cw.visitMethod(ACC_PUBLIC, "lastIndexOf", "(II)I", null, null); mv.visitCode(); mv.visitVarInsn(ALOAD, 0); mv.visitFieldInsn(GETFIELD, "java/lang/String", "offset", "I"); mv.visitVarInsn(ISTORE, 3); mv.visitVarInsn(ALOAD, 0); mv.visitFieldInsn(GETFIELD, "java/lang/String", "value", "[C"); mv.visitVarInsn(ASTORE, 4); mv.visitVarInsn(ALOAD, 0); mv.visitFieldInsn(GETFIELD, "java/lang/String", "offset", "I"); mv.visitVarInsn(ILOAD, 2); mv.visitVarInsn(ALOAD, 0); mv.visitFieldInsn(GETFIELD, "java/lang/String", "count", "I"); Label l0 = new Label(); mv.visitJumpInsn(IF_ICMPLT, l0); mv.visitVarInsn(ALOAD, 0); mv.visitFieldInsn(GETFIELD, "java/lang/String", "count", "I"); mv.visitInsn(ICONST_1); mv.visitInsn(ISUB); Label l1 = new Label(); mv.visitJumpInsn(GOTO, l1); mv.visitLabel(l0); mv.visitVarInsn(ILOAD, 2); mv.visitLabel(l1); mv.visitInsn(IADD); mv.visitVarInsn(ISTORE, 5); mv.visitVarInsn(ILOAD, 1); mv.visitLdcInsn(new Integer(65536)); Label l2 = new Label(); mv.visitJumpInsn(IF_ICMPGE, l2); Label l3 = new Label(); mv.visitLabel(l3); mv.visitVarInsn(ILOAD, 5); mv.visitVarInsn(ILOAD, 3); Label l4 = new Label(); mv.visitJumpInsn(IF_ICMPLT, l4); mv.visitVarInsn(ALOAD, 4); mv.visitVarInsn(ILOAD, 5); mv.visitInsn(CALOAD); mv.visitVarInsn(ILOAD, 1); Label l5 = new Label(); mv.visitJumpInsn(IF_ICMPNE, l5); mv.visitVarInsn(ILOAD, 5); mv.visitVarInsn(ALOAD, 0); mv.visitFieldInsn(GETFIELD, "java/lang/String", "offset", "I"); mv.visitInsn(ISUB); mv.visitInsn(IRETURN); mv.visitLabel(l5); mv.visitIincInsn(5, -1); mv.visitJumpInsn(GOTO, l3); mv.visitLabel(l4); mv.visitInsn(ICONST_M1); mv.visitInsn(IRETURN); mv.visitLabel(l2); mv.visitVarInsn(ALOAD, 0); mv.visitFieldInsn(GETFIELD, "java/lang/String", "offset", "I"); mv.visitVarInsn(ALOAD, 0); mv.visitFieldInsn(GETFIELD, "java/lang/String", "count", "I"); mv.visitInsn(IADD); mv.visitVarInsn(ISTORE, 6); mv.visitVarInsn(ILOAD, 1); mv.visitLdcInsn(new Integer(1114111)); Label l6 = new Label(); mv.visitJumpInsn(IF_ICMPGT, l6); mv.visitVarInsn(ILOAD, 1); mv.visitMethodInsn(INVOKESTATIC, "java/lang/Character", "toChars", "(I)[C"); mv.visitVarInsn(ASTORE, 7); Label l7 = new Label(); mv.visitLabel(l7); mv.visitVarInsn(ILOAD, 5); mv.visitVarInsn(ILOAD, 3); mv.visitJumpInsn(IF_ICMPLT, l6); mv.visitVarInsn(ALOAD, 4); mv.visitVarInsn(ILOAD, 5); mv.visitInsn(CALOAD); mv.visitVarInsn(ALOAD, 7); mv.visitInsn(ICONST_0); mv.visitInsn(CALOAD); Label l8 = new Label(); mv.visitJumpInsn(IF_ICMPNE, l8); mv.visitVarInsn(ILOAD, 5); mv.visitInsn(ICONST_1); mv.visitInsn(IADD); mv.visitVarInsn(ILOAD, 6); Label l9 = new Label(); mv.visitJumpInsn(IF_ICMPNE, l9); mv.visitJumpInsn(GOTO, l6); mv.visitLabel(l9); mv.visitVarInsn(ALOAD, 4); mv.visitVarInsn(ILOAD, 5); mv.visitInsn(ICONST_1); mv.visitInsn(IADD); mv.visitInsn(CALOAD); mv.visitVarInsn(ALOAD, 7); mv.visitInsn(ICONST_1); mv.visitInsn(CALOAD); mv.visitJumpInsn(IF_ICMPNE, l8); mv.visitVarInsn(ILOAD, 5); mv.visitVarInsn(ALOAD, 0); mv.visitFieldInsn(GETFIELD, "java/lang/String", "offset", "I"); mv.visitInsn(ISUB); mv.visitInsn(IRETURN); mv.visitLabel(l8); mv.visitIincInsn(5, -1); mv.visitJumpInsn(GOTO, l7); mv.visitLabel(l6); mv.visitInsn(ICONST_M1); mv.visitInsn(IRETURN); mv.visitMaxs(3, 8); mv.visitEnd(); } { mv = cw.visitMethod(ACC_PUBLIC, "indexOf", "(Ljava/lang/String;)I", null, null); mv.visitCode(); mv.visitVarInsn(ALOAD, 0); mv.visitVarInsn(ALOAD, 1); mv.visitInsn(ICONST_0); mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/String", "indexOf", "(Ljava/lang/String;I)I"); mv.visitInsn(IRETURN); mv.visitMaxs(3, 2); mv.visitEnd(); } { mv = cw.visitMethod(ACC_PUBLIC, "indexOf", "(Ljava/lang/String;I)I", null, null); mv.visitCode(); mv.visitVarInsn(ALOAD, 0); mv.visitFieldInsn(GETFIELD, "java/lang/String", "value", "[C"); mv.visitVarInsn(ALOAD, 0); mv.visitFieldInsn(GETFIELD, "java/lang/String", "offset", "I"); mv.visitVarInsn(ALOAD, 0); mv.visitFieldInsn(GETFIELD, "java/lang/String", "count", "I"); mv.visitVarInsn(ALOAD, 1); mv.visitFieldInsn(GETFIELD, "java/lang/String", "value", "[C"); mv.visitVarInsn(ALOAD, 1); mv.visitFieldInsn(GETFIELD, "java/lang/String", "offset", "I"); mv.visitVarInsn(ALOAD, 1); mv.visitFieldInsn(GETFIELD, "java/lang/String", "count", "I"); mv.visitVarInsn(ILOAD, 2); mv.visitMethodInsn(INVOKESTATIC, "java/lang/String", "indexOf", "([CII[CIII)I"); mv.visitInsn(IRETURN); mv.visitMaxs(7, 3); mv.visitEnd(); } { mv = cw.visitMethod(ACC_STATIC, "indexOf", "([CII[CIII)I", null, null); mv.visitCode(); mv.visitVarInsn(ILOAD, 6); mv.visitVarInsn(ILOAD, 2); Label l0 = new Label(); mv.visitJumpInsn(IF_ICMPLT, l0); mv.visitVarInsn(ILOAD, 5); Label l1 = new Label(); mv.visitJumpInsn(IFNE, l1); mv.visitVarInsn(ILOAD, 2); Label l2 = new Label(); mv.visitJumpInsn(GOTO, l2); mv.visitLabel(l1); mv.visitInsn(ICONST_M1); mv.visitLabel(l2); mv.visitInsn(IRETURN); mv.visitLabel(l0); mv.visitVarInsn(ILOAD, 6); Label l3 = new Label(); mv.visitJumpInsn(IFGE, l3); mv.visitInsn(ICONST_0); mv.visitVarInsn(ISTORE, 6); mv.visitLabel(l3); mv.visitVarInsn(ILOAD, 5); Label l4 = new Label(); mv.visitJumpInsn(IFNE, l4); mv.visitVarInsn(ILOAD, 6); mv.visitInsn(IRETURN); mv.visitLabel(l4); mv.visitVarInsn(ALOAD, 3); mv.visitVarInsn(ILOAD, 4); mv.visitInsn(CALOAD); mv.visitVarInsn(ISTORE, 7); mv.visitVarInsn(ILOAD, 1); mv.visitVarInsn(ILOAD, 2); mv.visitVarInsn(ILOAD, 5); mv.visitInsn(ISUB); mv.visitInsn(IADD); mv.visitVarInsn(ISTORE, 8); mv.visitVarInsn(ILOAD, 1); mv.visitVarInsn(ILOAD, 6); mv.visitInsn(IADD); mv.visitVarInsn(ISTORE, 9); Label l5 = new Label(); mv.visitLabel(l5); mv.visitVarInsn(ILOAD, 9); mv.visitVarInsn(ILOAD, 8); Label l6 = new Label(); mv.visitJumpInsn(IF_ICMPGT, l6); mv.visitVarInsn(ALOAD, 0); mv.visitVarInsn(ILOAD, 9); mv.visitInsn(CALOAD); mv.visitVarInsn(ILOAD, 7); Label l7 = new Label(); mv.visitJumpInsn(IF_ICMPEQ, l7); Label l8 = new Label(); mv.visitLabel(l8); mv.visitIincInsn(9, 1); mv.visitVarInsn(ILOAD, 9); mv.visitVarInsn(ILOAD, 8); mv.visitJumpInsn(IF_ICMPGT, l7); mv.visitVarInsn(ALOAD, 0); mv.visitVarInsn(ILOAD, 9); mv.visitInsn(CALOAD); mv.visitVarInsn(ILOAD, 7); mv.visitJumpInsn(IF_ICMPEQ, l7); mv.visitJumpInsn(GOTO, l8); mv.visitLabel(l7); mv.visitVarInsn(ILOAD, 9); mv.visitVarInsn(ILOAD, 8); Label l9 = new Label(); mv.visitJumpInsn(IF_ICMPGT, l9); mv.visitVarInsn(ILOAD, 9); mv.visitInsn(ICONST_1); mv.visitInsn(IADD); mv.visitVarInsn(ISTORE, 10); mv.visitVarInsn(ILOAD, 10); mv.visitVarInsn(ILOAD, 5); mv.visitInsn(IADD); mv.visitInsn(ICONST_1); mv.visitInsn(ISUB); mv.visitVarInsn(ISTORE, 11); mv.visitVarInsn(ILOAD, 4); mv.visitInsn(ICONST_1); mv.visitInsn(IADD); mv.visitVarInsn(ISTORE, 12); Label l10 = new Label(); mv.visitLabel(l10); mv.visitVarInsn(ILOAD, 10); mv.visitVarInsn(ILOAD, 11); Label l11 = new Label(); mv.visitJumpInsn(IF_ICMPGE, l11); mv.visitVarInsn(ALOAD, 0); mv.visitVarInsn(ILOAD, 10); mv.visitInsn(CALOAD); mv.visitVarInsn(ALOAD, 3); mv.visitVarInsn(ILOAD, 12); mv.visitInsn(CALOAD); mv.visitJumpInsn(IF_ICMPNE, l11); mv.visitIincInsn(10, 1); mv.visitIincInsn(12, 1); mv.visitJumpInsn(GOTO, l10); mv.visitLabel(l11); mv.visitVarInsn(ILOAD, 10); mv.visitVarInsn(ILOAD, 11); mv.visitJumpInsn(IF_ICMPNE, l9); mv.visitVarInsn(ILOAD, 9); mv.visitVarInsn(ILOAD, 1); mv.visitInsn(ISUB); mv.visitInsn(IRETURN); mv.visitLabel(l9); mv.visitIincInsn(9, 1); mv.visitJumpInsn(GOTO, l5); mv.visitLabel(l6); mv.visitInsn(ICONST_M1); mv.visitInsn(IRETURN); mv.visitMaxs(3, 13); mv.visitEnd(); } { mv = cw.visitMethod(ACC_PUBLIC, "lastIndexOf", "(Ljava/lang/String;)I", null, null); mv.visitCode(); mv.visitVarInsn(ALOAD, 0); mv.visitVarInsn(ALOAD, 1); mv.visitVarInsn(ALOAD, 0); mv.visitFieldInsn(GETFIELD, "java/lang/String", "count", "I"); mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/String", "lastIndexOf", "(Ljava/lang/String;I)I"); mv.visitInsn(IRETURN); mv.visitMaxs(3, 2); mv.visitEnd(); } { mv = cw.visitMethod(ACC_PUBLIC, "lastIndexOf", "(Ljava/lang/String;I)I", null, null); mv.visitCode(); mv.visitVarInsn(ALOAD, 0); mv.visitFieldInsn(GETFIELD, "java/lang/String", "value", "[C"); mv.visitVarInsn(ALOAD, 0); mv.visitFieldInsn(GETFIELD, "java/lang/String", "offset", "I"); mv.visitVarInsn(ALOAD, 0); mv.visitFieldInsn(GETFIELD, "java/lang/String", "count", "I"); mv.visitVarInsn(ALOAD, 1); mv.visitFieldInsn(GETFIELD, "java/lang/String", "value", "[C"); mv.visitVarInsn(ALOAD, 1); mv.visitFieldInsn(GETFIELD, "java/lang/String", "offset", "I"); mv.visitVarInsn(ALOAD, 1); mv.visitFieldInsn(GETFIELD, "java/lang/String", "count", "I"); mv.visitVarInsn(ILOAD, 2); mv.visitMethodInsn(INVOKESTATIC, "java/lang/String", "lastIndexOf", "([CII[CIII)I"); mv.visitInsn(IRETURN); mv.visitMaxs(7, 3); mv.visitEnd(); } { mv = cw.visitMethod(ACC_STATIC, "lastIndexOf", "([CII[CIII)I", null, null); mv.visitCode(); mv.visitVarInsn(ILOAD, 2); mv.visitVarInsn(ILOAD, 5); mv.visitInsn(ISUB); mv.visitVarInsn(ISTORE, 7); mv.visitVarInsn(ILOAD, 6); Label l0 = new Label(); mv.visitJumpInsn(IFGE, l0); mv.visitInsn(ICONST_M1); mv.visitInsn(IRETURN); mv.visitLabel(l0); mv.visitVarInsn(ILOAD, 6); mv.visitVarInsn(ILOAD, 7); Label l1 = new Label(); mv.visitJumpInsn(IF_ICMPLE, l1); mv.visitVarInsn(ILOAD, 7); mv.visitVarInsn(ISTORE, 6); mv.visitLabel(l1); mv.visitVarInsn(ILOAD, 5); Label l2 = new Label(); mv.visitJumpInsn(IFNE, l2); mv.visitVarInsn(ILOAD, 6); mv.visitInsn(IRETURN); mv.visitLabel(l2); mv.visitVarInsn(ILOAD, 4); mv.visitVarInsn(ILOAD, 5); mv.visitInsn(IADD); mv.visitInsn(ICONST_1); mv.visitInsn(ISUB); mv.visitVarInsn(ISTORE, 8); mv.visitVarInsn(ALOAD, 3); mv.visitVarInsn(ILOAD, 8); mv.visitInsn(CALOAD); mv.visitVarInsn(ISTORE, 9); mv.visitVarInsn(ILOAD, 1); mv.visitVarInsn(ILOAD, 5); mv.visitInsn(IADD); mv.visitInsn(ICONST_1); mv.visitInsn(ISUB); mv.visitVarInsn(ISTORE, 10); mv.visitVarInsn(ILOAD, 10); mv.visitVarInsn(ILOAD, 6); mv.visitInsn(IADD); mv.visitVarInsn(ISTORE, 11); Label l3 = new Label(); mv.visitLabel(l3); mv.visitVarInsn(ILOAD, 11); mv.visitVarInsn(ILOAD, 10); Label l4 = new Label(); mv.visitJumpInsn(IF_ICMPLT, l4); mv.visitVarInsn(ALOAD, 0); mv.visitVarInsn(ILOAD, 11); mv.visitInsn(CALOAD); mv.visitVarInsn(ILOAD, 9); mv.visitJumpInsn(IF_ICMPEQ, l4); mv.visitIincInsn(11, -1); mv.visitJumpInsn(GOTO, l3); mv.visitLabel(l4); mv.visitVarInsn(ILOAD, 11); mv.visitVarInsn(ILOAD, 10); Label l5 = new Label(); mv.visitJumpInsn(IF_ICMPGE, l5); mv.visitInsn(ICONST_M1); mv.visitInsn(IRETURN); mv.visitLabel(l5); mv.visitVarInsn(ILOAD, 11); mv.visitInsn(ICONST_1); mv.visitInsn(ISUB); mv.visitVarInsn(ISTORE, 12); mv.visitVarInsn(ILOAD, 12); mv.visitVarInsn(ILOAD, 5); mv.visitInsn(ICONST_1); mv.visitInsn(ISUB); mv.visitInsn(ISUB); mv.visitVarInsn(ISTORE, 13); mv.visitVarInsn(ILOAD, 8); mv.visitInsn(ICONST_1); mv.visitInsn(ISUB); mv.visitVarInsn(ISTORE, 14); Label l6 = new Label(); mv.visitLabel(l6); mv.visitVarInsn(ILOAD, 12); mv.visitVarInsn(ILOAD, 13); Label l7 = new Label(); mv.visitJumpInsn(IF_ICMPLE, l7); mv.visitVarInsn(ALOAD, 0); mv.visitVarInsn(ILOAD, 12); mv.visitIincInsn(12, -1); mv.visitInsn(CALOAD); mv.visitVarInsn(ALOAD, 3); mv.visitVarInsn(ILOAD, 14); mv.visitIincInsn(14, -1); mv.visitInsn(CALOAD); mv.visitJumpInsn(IF_ICMPEQ, l6); mv.visitIincInsn(11, -1); mv.visitJumpInsn(GOTO, l3); mv.visitLabel(l7); mv.visitVarInsn(ILOAD, 13); mv.visitVarInsn(ILOAD, 1); mv.visitInsn(ISUB); mv.visitInsn(ICONST_1); mv.visitInsn(IADD); mv.visitInsn(IRETURN); mv.visitMaxs(3, 15); mv.visitEnd(); } { mv = cw.visitMethod(ACC_PUBLIC, "substring", "(I)Ljava/lang/String;", null, null); mv.visitCode(); mv.visitVarInsn(ALOAD, 0); mv.visitVarInsn(ILOAD, 1); mv.visitVarInsn(ALOAD, 0); mv.visitFieldInsn(GETFIELD, "java/lang/String", "count", "I"); mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/String", "substring", "(II)Ljava/lang/String;"); mv.visitInsn(ARETURN); mv.visitMaxs(3, 2); mv.visitEnd(); } { mv = cw.visitMethod(ACC_PUBLIC, "substring", "(II)Ljava/lang/String;", null, null); mv.visitCode(); mv.visitVarInsn(ILOAD, 1); Label l0 = new Label(); mv.visitJumpInsn(IFGE, l0); mv.visitTypeInsn(NEW, "java/lang/StringIndexOutOfBoundsException"); mv.visitInsn(DUP); mv.visitVarInsn(ILOAD, 1); mv.visitMethodInsn(INVOKESPECIAL, "java/lang/StringIndexOutOfBoundsException", "<init>", "(I)V"); mv.visitInsn(ATHROW); mv.visitLabel(l0); mv.visitVarInsn(ILOAD, 2); mv.visitVarInsn(ALOAD, 0); mv.visitFieldInsn(GETFIELD, "java/lang/String", "count", "I"); Label l1 = new Label(); mv.visitJumpInsn(IF_ICMPLE, l1); mv.visitTypeInsn(NEW, "java/lang/StringIndexOutOfBoundsException"); mv.visitInsn(DUP); mv.visitVarInsn(ILOAD, 2); mv.visitMethodInsn(INVOKESPECIAL, "java/lang/StringIndexOutOfBoundsException", "<init>", "(I)V"); mv.visitInsn(ATHROW); mv.visitLabel(l1); mv.visitVarInsn(ILOAD, 1); mv.visitVarInsn(ILOAD, 2); Label l2 = new Label(); mv.visitJumpInsn(IF_ICMPLE, l2); mv.visitTypeInsn(NEW, "java/lang/StringIndexOutOfBoundsException"); mv.visitInsn(DUP); mv.visitVarInsn(ILOAD, 2); mv.visitVarInsn(ILOAD, 1); mv.visitInsn(ISUB); mv.visitMethodInsn(INVOKESPECIAL, "java/lang/StringIndexOutOfBoundsException", "<init>", "(I)V"); mv.visitInsn(ATHROW); mv.visitLabel(l2); mv.visitVarInsn(ILOAD, 1); Label l3 = new Label(); mv.visitJumpInsn(IFNE, l3); mv.visitVarInsn(ILOAD, 2); mv.visitVarInsn(ALOAD, 0); mv.visitFieldInsn(GETFIELD, "java/lang/String", "count", "I"); mv.visitJumpInsn(IF_ICMPNE, l3); mv.visitVarInsn(ALOAD, 0); Label l4 = new Label(); mv.visitJumpInsn(GOTO, l4); mv.visitLabel(l3); mv.visitTypeInsn(NEW, "java/lang/String"); mv.visitInsn(DUP); mv.visitVarInsn(ALOAD, 0); mv.visitFieldInsn(GETFIELD, "java/lang/String", "offset", "I"); mv.visitVarInsn(ILOAD, 1); mv.visitInsn(IADD); mv.visitVarInsn(ILOAD, 2); mv.visitVarInsn(ILOAD, 1); mv.visitInsn(ISUB); mv.visitVarInsn(ALOAD, 0); mv.visitFieldInsn(GETFIELD, "java/lang/String", "value", "[C"); mv.visitMethodInsn(INVOKESPECIAL, "java/lang/String", "<init>", "(II[C)V"); mv.visitLabel(l4); mv.visitInsn(ARETURN); mv.visitMaxs(5, 3); mv.visitEnd(); } { mv = cw.visitMethod(ACC_PUBLIC, "subSequence", "(II)Ljava/lang/CharSequence;", null, null); mv.visitCode(); mv.visitVarInsn(ALOAD, 0); mv.visitVarInsn(ILOAD, 1); mv.visitVarInsn(ILOAD, 2); mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/String", "substring", "(II)Ljava/lang/String;"); mv.visitInsn(ARETURN); mv.visitMaxs(3, 3); mv.visitEnd(); } { mv = cw.visitMethod(ACC_PUBLIC, "concat", "(Ljava/lang/String;)Ljava/lang/String;", null, null); mv.visitCode(); mv.visitVarInsn(ALOAD, 1); mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/String", "length", "()I"); mv.visitVarInsn(ISTORE, 2); mv.visitVarInsn(ILOAD, 2); Label l0 = new Label(); mv.visitJumpInsn(IFNE, l0); mv.visitVarInsn(ALOAD, 0); mv.visitInsn(ARETURN); mv.visitLabel(l0); mv.visitVarInsn(ALOAD, 0); mv.visitFieldInsn(GETFIELD, "java/lang/String", "count", "I"); mv.visitVarInsn(ILOAD, 2); mv.visitInsn(IADD); mv.visitIntInsn(NEWARRAY, T_CHAR); mv.visitVarInsn(ASTORE, 3); mv.visitVarInsn(ALOAD, 0); mv.visitInsn(ICONST_0); mv.visitVarInsn(ALOAD, 0); mv.visitFieldInsn(GETFIELD, "java/lang/String", "count", "I"); mv.visitVarInsn(ALOAD, 3); mv.visitInsn(ICONST_0); mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/String", "getChars", "(II[CI)V"); mv.visitVarInsn(ALOAD, 1); mv.visitInsn(ICONST_0); mv.visitVarInsn(ILOAD, 2); mv.visitVarInsn(ALOAD, 3); mv.visitVarInsn(ALOAD, 0); mv.visitFieldInsn(GETFIELD, "java/lang/String", "count", "I"); mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/String", "getChars", "(II[CI)V"); mv.visitTypeInsn(NEW, "java/lang/String"); mv.visitInsn(DUP); mv.visitInsn(ICONST_0); mv.visitVarInsn(ALOAD, 0); mv.visitFieldInsn(GETFIELD, "java/lang/String", "count", "I"); mv.visitVarInsn(ILOAD, 2); mv.visitInsn(IADD); mv.visitVarInsn(ALOAD, 3); mv.visitMethodInsn(INVOKESPECIAL, "java/lang/String", "<init>", "(II[C)V"); mv.visitInsn(ARETURN); mv.visitMaxs(5, 4); mv.visitEnd(); } { mv = cw.visitMethod(ACC_PUBLIC, "replace", "(CC)Ljava/lang/String;", null, null); mv.visitCode(); mv.visitVarInsn(ILOAD, 1); mv.visitVarInsn(ILOAD, 2); Label l0 = new Label(); mv.visitJumpInsn(IF_ICMPEQ, l0); mv.visitVarInsn(ALOAD, 0); mv.visitFieldInsn(GETFIELD, "java/lang/String", "count", "I"); mv.visitVarInsn(ISTORE, 3); mv.visitInsn(ICONST_M1); mv.visitVarInsn(ISTORE, 4); mv.visitVarInsn(ALOAD, 0); mv.visitFieldInsn(GETFIELD, "java/lang/String", "value", "[C"); mv.visitVarInsn(ASTORE, 5); mv.visitVarInsn(ALOAD, 0); mv.visitFieldInsn(GETFIELD, "java/lang/String", "offset", "I"); mv.visitVarInsn(ISTORE, 6); Label l1 = new Label(); mv.visitLabel(l1); mv.visitIincInsn(4, 1); mv.visitVarInsn(ILOAD, 4); mv.visitVarInsn(ILOAD, 3); Label l2 = new Label(); mv.visitJumpInsn(IF_ICMPGE, l2); mv.visitVarInsn(ALOAD, 5); mv.visitVarInsn(ILOAD, 6); mv.visitVarInsn(ILOAD, 4); mv.visitInsn(IADD); mv.visitInsn(CALOAD); mv.visitVarInsn(ILOAD, 1); mv.visitJumpInsn(IF_ICMPNE, l1); mv.visitJumpInsn(GOTO, l2); mv.visitLabel(l2); mv.visitVarInsn(ILOAD, 4); mv.visitVarInsn(ILOAD, 3); mv.visitJumpInsn(IF_ICMPGE, l0); mv.visitVarInsn(ILOAD, 3); mv.visitIntInsn(NEWARRAY, T_CHAR); mv.visitVarInsn(ASTORE, 7); mv.visitInsn(ICONST_0); mv.visitVarInsn(ISTORE, 8); Label l3 = new Label(); mv.visitLabel(l3); mv.visitVarInsn(ILOAD, 8); mv.visitVarInsn(ILOAD, 4); Label l4 = new Label(); mv.visitJumpInsn(IF_ICMPGE, l4); mv.visitVarInsn(ALOAD, 7); mv.visitVarInsn(ILOAD, 8); mv.visitVarInsn(ALOAD, 5); mv.visitVarInsn(ILOAD, 6); mv.visitVarInsn(ILOAD, 8); mv.visitInsn(IADD); mv.visitInsn(CALOAD); mv.visitInsn(CASTORE); mv.visitIincInsn(8, 1); mv.visitJumpInsn(GOTO, l3); mv.visitLabel(l4); mv.visitVarInsn(ILOAD, 4); mv.visitVarInsn(ILOAD, 3); Label l5 = new Label(); mv.visitJumpInsn(IF_ICMPGE, l5); mv.visitVarInsn(ALOAD, 5); mv.visitVarInsn(ILOAD, 6); mv.visitVarInsn(ILOAD, 4); mv.visitInsn(IADD); mv.visitInsn(CALOAD); mv.visitVarInsn(ISTORE, 8); mv.visitVarInsn(ALOAD, 7); mv.visitVarInsn(ILOAD, 4); mv.visitVarInsn(ILOAD, 8); mv.visitVarInsn(ILOAD, 1); Label l6 = new Label(); mv.visitJumpInsn(IF_ICMPNE, l6); mv.visitVarInsn(ILOAD, 2); Label l7 = new Label(); mv.visitJumpInsn(GOTO, l7); mv.visitLabel(l6); mv.visitVarInsn(ILOAD, 8); mv.visitLabel(l7); mv.visitInsn(CASTORE); mv.visitIincInsn(4, 1); mv.visitJumpInsn(GOTO, l4); mv.visitLabel(l5); mv.visitTypeInsn(NEW, "java/lang/String"); mv.visitInsn(DUP); mv.visitInsn(ICONST_0); mv.visitVarInsn(ILOAD, 3); mv.visitVarInsn(ALOAD, 7); mv.visitMethodInsn(INVOKESPECIAL, "java/lang/String", "<init>", "(II[C)V"); mv.visitInsn(ARETURN); mv.visitLabel(l0); mv.visitVarInsn(ALOAD, 0); mv.visitInsn(ARETURN); mv.visitMaxs(5, 9); mv.visitEnd(); } { mv = cw.visitMethod(ACC_PUBLIC, "matches", "(Ljava/lang/String;)Z", null, null); mv.visitCode(); mv.visitVarInsn(ALOAD, 1); mv.visitVarInsn(ALOAD, 0); mv.visitMethodInsn(INVOKESTATIC, "java/util/regex/Pattern", "matches", "(Ljava/lang/String;Ljava/lang/CharSequence;)Z"); mv.visitInsn(IRETURN); mv.visitMaxs(2, 2); mv.visitEnd(); } { mv = cw.visitMethod(ACC_PUBLIC, "contains", "(Ljava/lang/CharSequence;)Z", null, null); mv.visitCode(); mv.visitVarInsn(ALOAD, 0); mv.visitVarInsn(ALOAD, 1); mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Object", "toString", "()Ljava/lang/String;"); mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/String", "indexOf", "(Ljava/lang/String;)I"); mv.visitInsn(ICONST_M1); Label l0 = new Label(); mv.visitJumpInsn(IF_ICMPLE, l0); mv.visitInsn(ICONST_1); Label l1 = new Label(); mv.visitJumpInsn(GOTO, l1); mv.visitLabel(l0); mv.visitInsn(ICONST_0); mv.visitLabel(l1); mv.visitInsn(IRETURN); mv.visitMaxs(2, 2); mv.visitEnd(); } { mv = cw.visitMethod(ACC_PUBLIC, "replaceFirst", "(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;", null, null); mv.visitCode(); mv.visitVarInsn(ALOAD, 1); mv.visitMethodInsn(INVOKESTATIC, "java/util/regex/Pattern", "compile", "(Ljava/lang/String;)Ljava/util/regex/Pattern;"); mv.visitVarInsn(ALOAD, 0); mv.visitMethodInsn(INVOKEVIRTUAL, "java/util/regex/Pattern", "matcher", "(Ljava/lang/CharSequence;)Ljava/util/regex/Matcher;"); mv.visitVarInsn(ALOAD, 2); mv.visitMethodInsn(INVOKEVIRTUAL, "java/util/regex/Matcher", "replaceFirst", "(Ljava/lang/String;)Ljava/lang/String;"); mv.visitInsn(ARETURN); mv.visitMaxs(2, 3); mv.visitEnd(); } { mv = cw.visitMethod(ACC_PUBLIC, "replaceAll", "(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;", null, null); mv.visitCode(); mv.visitVarInsn(ALOAD, 1); mv.visitMethodInsn(INVOKESTATIC, "java/util/regex/Pattern", "compile", "(Ljava/lang/String;)Ljava/util/regex/Pattern;"); mv.visitVarInsn(ALOAD, 0); mv.visitMethodInsn(INVOKEVIRTUAL, "java/util/regex/Pattern", "matcher", "(Ljava/lang/CharSequence;)Ljava/util/regex/Matcher;"); mv.visitVarInsn(ALOAD, 2); mv.visitMethodInsn(INVOKEVIRTUAL, "java/util/regex/Matcher", "replaceAll", "(Ljava/lang/String;)Ljava/lang/String;"); mv.visitInsn(ARETURN); mv.visitMaxs(2, 3); mv.visitEnd(); } { mv = cw.visitMethod(ACC_PUBLIC, "replace", "(Ljava/lang/CharSequence;Ljava/lang/CharSequence;)Ljava/lang/String;", null, null); mv.visitCode(); mv.visitVarInsn(ALOAD, 1); mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Object", "toString", "()Ljava/lang/String;"); mv.visitIntInsn(BIPUSH, 16); mv.visitMethodInsn(INVOKESTATIC, "java/util/regex/Pattern", "compile", "(Ljava/lang/String;I)Ljava/util/regex/Pattern;"); mv.visitVarInsn(ALOAD, 0); mv.visitMethodInsn(INVOKEVIRTUAL, "java/util/regex/Pattern", "matcher", "(Ljava/lang/CharSequence;)Ljava/util/regex/Matcher;"); mv.visitVarInsn(ALOAD, 2); mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Object", "toString", "()Ljava/lang/String;"); mv.visitMethodInsn(INVOKESTATIC, "java/util/regex/Matcher", "quoteReplacement", "(Ljava/lang/String;)Ljava/lang/String;"); mv.visitMethodInsn(INVOKEVIRTUAL, "java/util/regex/Matcher", "replaceAll", "(Ljava/lang/String;)Ljava/lang/String;"); mv.visitInsn(ARETURN); mv.visitMaxs(2, 3); mv.visitEnd(); } { mv = cw.visitMethod(ACC_PUBLIC, "split", "(Ljava/lang/String;I)[Ljava/lang/String;", null, null); mv.visitCode(); mv.visitVarInsn(ALOAD, 1); mv.visitMethodInsn(INVOKESTATIC, "java/util/regex/Pattern", "compile", "(Ljava/lang/String;)Ljava/util/regex/Pattern;"); mv.visitVarInsn(ALOAD, 0); mv.visitVarInsn(ILOAD, 2); mv.visitMethodInsn(INVOKEVIRTUAL, "java/util/regex/Pattern", "split", "(Ljava/lang/CharSequence;I)[Ljava/lang/String;"); mv.visitInsn(ARETURN); mv.visitMaxs(3, 3); mv.visitEnd(); } { mv = cw.visitMethod(ACC_PUBLIC, "split", "(Ljava/lang/String;)[Ljava/lang/String;", null, null); mv.visitCode(); mv.visitVarInsn(ALOAD, 0); mv.visitVarInsn(ALOAD, 1); mv.visitInsn(ICONST_0); mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/String", "split", "(Ljava/lang/String;I)[Ljava/lang/String;"); mv.visitInsn(ARETURN); mv.visitMaxs(3, 2); mv.visitEnd(); } { mv = cw.visitMethod(ACC_PUBLIC, "toLowerCase", "(Ljava/util/Locale;)Ljava/lang/String;", null, null); mv.visitCode(); mv.visitVarInsn(ALOAD, 1); Label l0 = new Label(); mv.visitJumpInsn(IFNONNULL, l0); mv.visitTypeInsn(NEW, "java/lang/NullPointerException"); mv.visitInsn(DUP); mv.visitMethodInsn(INVOKESPECIAL, "java/lang/NullPointerException", "<init>", "()V"); mv.visitInsn(ATHROW); mv.visitLabel(l0); mv.visitInsn(ICONST_0); mv.visitVarInsn(ISTORE, 2); Label l1 = new Label(); mv.visitLabel(l1); mv.visitVarInsn(ILOAD, 2); mv.visitVarInsn(ALOAD, 0); mv.visitFieldInsn(GETFIELD, "java/lang/String", "count", "I"); Label l2 = new Label(); mv.visitJumpInsn(IF_ICMPGE, l2); mv.visitVarInsn(ALOAD, 0); mv.visitFieldInsn(GETFIELD, "java/lang/String", "value", "[C"); mv.visitVarInsn(ALOAD, 0); mv.visitFieldInsn(GETFIELD, "java/lang/String", "offset", "I"); mv.visitVarInsn(ILOAD, 2); mv.visitInsn(IADD); mv.visitInsn(CALOAD); mv.visitVarInsn(ISTORE, 3); mv.visitVarInsn(ILOAD, 3); mv.visitLdcInsn(new Integer(55296)); Label l3 = new Label(); mv.visitJumpInsn(IF_ICMPLT, l3); mv.visitVarInsn(ILOAD, 3); mv.visitLdcInsn(new Integer(56319)); mv.visitJumpInsn(IF_ICMPGT, l3); mv.visitVarInsn(ALOAD, 0); mv.visitVarInsn(ILOAD, 2); mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/String", "codePointAt", "(I)I"); mv.visitVarInsn(ISTORE, 4); mv.visitVarInsn(ILOAD, 4); mv.visitVarInsn(ILOAD, 4); mv.visitMethodInsn(INVOKESTATIC, "java/lang/Character", "toLowerCase", "(I)I"); Label l4 = new Label(); mv.visitJumpInsn(IF_ICMPEQ, l4); Label l5 = new Label(); mv.visitJumpInsn(GOTO, l5); mv.visitLabel(l4); mv.visitVarInsn(ILOAD, 2); mv.visitVarInsn(ILOAD, 4); mv.visitMethodInsn(INVOKESTATIC, "java/lang/Character", "charCount", "(I)I"); mv.visitInsn(IADD); mv.visitVarInsn(ISTORE, 2); Label l6 = new Label(); mv.visitJumpInsn(GOTO, l6); mv.visitLabel(l3); mv.visitVarInsn(ILOAD, 3); mv.visitVarInsn(ILOAD, 3); mv.visitMethodInsn(INVOKESTATIC, "java/lang/Character", "toLowerCase", "(C)C"); Label l7 = new Label(); mv.visitJumpInsn(IF_ICMPEQ, l7); mv.visitJumpInsn(GOTO, l5); mv.visitLabel(l7); mv.visitIincInsn(2, 1); mv.visitLabel(l6); mv.visitJumpInsn(GOTO, l1); mv.visitLabel(l2); mv.visitVarInsn(ALOAD, 0); mv.visitInsn(ARETURN); mv.visitLabel(l5); mv.visitVarInsn(ALOAD, 0); mv.visitFieldInsn(GETFIELD, "java/lang/String", "count", "I"); mv.visitIntInsn(NEWARRAY, T_CHAR); mv.visitVarInsn(ASTORE, 3); mv.visitInsn(ICONST_0); mv.visitVarInsn(ISTORE, 4); mv.visitVarInsn(ALOAD, 0); mv.visitFieldInsn(GETFIELD, "java/lang/String", "value", "[C"); mv.visitVarInsn(ALOAD, 0); mv.visitFieldInsn(GETFIELD, "java/lang/String", "offset", "I"); mv.visitVarInsn(ALOAD, 3); mv.visitInsn(ICONST_0); mv.visitVarInsn(ILOAD, 2); mv.visitMethodInsn(INVOKESTATIC, "java/lang/System", "arraycopy", "(Ljava/lang/Object;ILjava/lang/Object;II)V"); mv.visitVarInsn(ALOAD, 1); mv.visitMethodInsn(INVOKEVIRTUAL, "java/util/Locale", "getLanguage", "()Ljava/lang/String;"); mv.visitVarInsn(ASTORE, 5); mv.visitVarInsn(ALOAD, 5); mv.visitLdcInsn("tr"); Label l8 = new Label(); mv.visitJumpInsn(IF_ACMPEQ, l8); mv.visitVarInsn(ALOAD, 5); mv.visitLdcInsn("az"); mv.visitJumpInsn(IF_ACMPEQ, l8); mv.visitVarInsn(ALOAD, 5); mv.visitLdcInsn("lt"); Label l9 = new Label(); mv.visitJumpInsn(IF_ACMPNE, l9); mv.visitLabel(l8); mv.visitInsn(ICONST_1); Label l10 = new Label(); mv.visitJumpInsn(GOTO, l10); mv.visitLabel(l9); mv.visitInsn(ICONST_0); mv.visitLabel(l10); mv.visitVarInsn(ISTORE, 6); mv.visitVarInsn(ILOAD, 2); mv.visitVarInsn(ISTORE, 11); Label l11 = new Label(); mv.visitLabel(l11); mv.visitVarInsn(ILOAD, 11); mv.visitVarInsn(ALOAD, 0); mv.visitFieldInsn(GETFIELD, "java/lang/String", "count", "I"); Label l12 = new Label(); mv.visitJumpInsn(IF_ICMPGE, l12); mv.visitVarInsn(ALOAD, 0); mv.visitFieldInsn(GETFIELD, "java/lang/String", "value", "[C"); mv.visitVarInsn(ALOAD, 0); mv.visitFieldInsn(GETFIELD, "java/lang/String", "offset", "I"); mv.visitVarInsn(ILOAD, 11); mv.visitInsn(IADD); mv.visitInsn(CALOAD); mv.visitVarInsn(ISTORE, 9); mv.visitVarInsn(ILOAD, 9); mv.visitInsn(I2C); mv.visitLdcInsn(new Integer(55296)); Label l13 = new Label(); mv.visitJumpInsn(IF_ICMPLT, l13); mv.visitVarInsn(ILOAD, 9); mv.visitInsn(I2C); mv.visitLdcInsn(new Integer(56319)); mv.visitJumpInsn(IF_ICMPGT, l13); mv.visitVarInsn(ALOAD, 0); mv.visitVarInsn(ILOAD, 11); mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/String", "codePointAt", "(I)I"); mv.visitVarInsn(ISTORE, 9); mv.visitVarInsn(ILOAD, 9); mv.visitMethodInsn(INVOKESTATIC, "java/lang/Character", "charCount", "(I)I"); mv.visitVarInsn(ISTORE, 10); Label l14 = new Label(); mv.visitJumpInsn(GOTO, l14); mv.visitLabel(l13); mv.visitInsn(ICONST_1); mv.visitVarInsn(ISTORE, 10); mv.visitLabel(l14); mv.visitVarInsn(ILOAD, 6); Label l15 = new Label(); mv.visitJumpInsn(IFNE, l15); mv.visitVarInsn(ILOAD, 9); mv.visitIntInsn(SIPUSH, 931); Label l16 = new Label(); mv.visitJumpInsn(IF_ICMPNE, l16); mv.visitLabel(l15); mv.visitVarInsn(ALOAD, 0); mv.visitVarInsn(ILOAD, 11); mv.visitVarInsn(ALOAD, 1); mv.visitMethodInsn(INVOKESTATIC, "java/lang/ConditionalSpecialCasing", "toLowerCaseEx", "(Ljava/lang/String;ILjava/util/Locale;)I"); mv.visitVarInsn(ISTORE, 8); Label l17 = new Label(); mv.visitJumpInsn(GOTO, l17); mv.visitLabel(l16); mv.visitVarInsn(ILOAD, 9); mv.visitMethodInsn(INVOKESTATIC, "java/lang/Character", "toLowerCase", "(I)I"); mv.visitVarInsn(ISTORE, 8); mv.visitLabel(l17); mv.visitVarInsn(ILOAD, 8); mv.visitInsn(ICONST_M1); Label l18 = new Label(); mv.visitJumpInsn(IF_ICMPEQ, l18); mv.visitVarInsn(ILOAD, 8); mv.visitLdcInsn(new Integer(65536)); Label l19 = new Label(); mv.visitJumpInsn(IF_ICMPLT, l19); mv.visitLabel(l18); mv.visitVarInsn(ILOAD, 8); mv.visitInsn(ICONST_M1); Label l20 = new Label(); mv.visitJumpInsn(IF_ICMPNE, l20); mv.visitVarInsn(ALOAD, 0); mv.visitVarInsn(ILOAD, 11); mv.visitVarInsn(ALOAD, 1); mv.visitMethodInsn(INVOKESTATIC, "java/lang/ConditionalSpecialCasing", "toLowerCaseCharArray", "(Ljava/lang/String;ILjava/util/Locale;)[C"); mv.visitVarInsn(ASTORE, 7); Label l21 = new Label(); mv.visitJumpInsn(GOTO, l21); mv.visitLabel(l20); mv.visitVarInsn(ILOAD, 10); mv.visitInsn(ICONST_2); Label l22 = new Label(); mv.visitJumpInsn(IF_ICMPNE, l22); mv.visitVarInsn(ILOAD, 4); mv.visitVarInsn(ILOAD, 8); mv.visitVarInsn(ALOAD, 3); mv.visitVarInsn(ILOAD, 11); mv.visitVarInsn(ILOAD, 4); mv.visitInsn(IADD); mv.visitMethodInsn(INVOKESTATIC, "java/lang/Character", "toChars", "(I[CI)I"); mv.visitVarInsn(ILOAD, 10); mv.visitInsn(ISUB); mv.visitInsn(IADD); mv.visitVarInsn(ISTORE, 4); Label l23 = new Label(); mv.visitJumpInsn(GOTO, l23); mv.visitLabel(l22); mv.visitVarInsn(ILOAD, 8); mv.visitMethodInsn(INVOKESTATIC, "java/lang/Character", "toChars", "(I)[C"); mv.visitVarInsn(ASTORE, 7); mv.visitLabel(l21); mv.visitVarInsn(ALOAD, 7); mv.visitInsn(ARRAYLENGTH); mv.visitVarInsn(ISTORE, 12); mv.visitVarInsn(ILOAD, 12); mv.visitVarInsn(ILOAD, 10); Label l24 = new Label(); mv.visitJumpInsn(IF_ICMPLE, l24); mv.visitVarInsn(ALOAD, 3); mv.visitInsn(ARRAYLENGTH); mv.visitVarInsn(ILOAD, 12); mv.visitInsn(IADD); mv.visitVarInsn(ILOAD, 10); mv.visitInsn(ISUB); mv.visitIntInsn(NEWARRAY, T_CHAR); mv.visitVarInsn(ASTORE, 13); mv.visitVarInsn(ALOAD, 3); mv.visitInsn(ICONST_0); mv.visitVarInsn(ALOAD, 13); mv.visitInsn(ICONST_0); mv.visitVarInsn(ILOAD, 11); mv.visitVarInsn(ILOAD, 4); mv.visitInsn(IADD); mv.visitMethodInsn(INVOKESTATIC, "java/lang/System", "arraycopy", "(Ljava/lang/Object;ILjava/lang/Object;II)V"); mv.visitVarInsn(ALOAD, 13); mv.visitVarInsn(ASTORE, 3); mv.visitLabel(l24); mv.visitInsn(ICONST_0); mv.visitVarInsn(ISTORE, 13); Label l25 = new Label(); mv.visitLabel(l25); mv.visitVarInsn(ILOAD, 13); mv.visitVarInsn(ILOAD, 12); Label l26 = new Label(); mv.visitJumpInsn(IF_ICMPGE, l26); mv.visitVarInsn(ALOAD, 3); mv.visitVarInsn(ILOAD, 11); mv.visitVarInsn(ILOAD, 4); mv.visitInsn(IADD); mv.visitVarInsn(ILOAD, 13); mv.visitInsn(IADD); mv.visitVarInsn(ALOAD, 7); mv.visitVarInsn(ILOAD, 13); mv.visitInsn(CALOAD); mv.visitInsn(CASTORE); mv.visitIincInsn(13, 1); mv.visitJumpInsn(GOTO, l25); mv.visitLabel(l26); mv.visitVarInsn(ILOAD, 4); mv.visitVarInsn(ILOAD, 12); mv.visitVarInsn(ILOAD, 10); mv.visitInsn(ISUB); mv.visitInsn(IADD); mv.visitVarInsn(ISTORE, 4); mv.visitJumpInsn(GOTO, l23); mv.visitLabel(l19); mv.visitVarInsn(ALOAD, 3); mv.visitVarInsn(ILOAD, 11); mv.visitVarInsn(ILOAD, 4); mv.visitInsn(IADD); mv.visitVarInsn(ILOAD, 8); mv.visitInsn(I2C); mv.visitInsn(CASTORE); mv.visitLabel(l23); mv.visitVarInsn(ILOAD, 11); mv.visitVarInsn(ILOAD, 10); mv.visitInsn(IADD); mv.visitVarInsn(ISTORE, 11); mv.visitJumpInsn(GOTO, l11); mv.visitLabel(l12); mv.visitTypeInsn(NEW, "java/lang/String"); mv.visitInsn(DUP); mv.visitInsn(ICONST_0); mv.visitVarInsn(ALOAD, 0); mv.visitFieldInsn(GETFIELD, "java/lang/String", "count", "I"); mv.visitVarInsn(ILOAD, 4); mv.visitInsn(IADD); mv.visitVarInsn(ALOAD, 3); mv.visitMethodInsn(INVOKESPECIAL, "java/lang/String", "<init>", "(II[C)V"); mv.visitInsn(ARETURN); mv.visitMaxs(6, 14); mv.visitEnd(); } { mv = cw.visitMethod(ACC_PUBLIC, "toLowerCase", "()Ljava/lang/String;", null, null); mv.visitCode(); mv.visitVarInsn(ALOAD, 0); mv.visitMethodInsn(INVOKESTATIC, "java/util/Locale", "getDefault", "()Ljava/util/Locale;"); mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/String", "toLowerCase", "(Ljava/util/Locale;)Ljava/lang/String;"); mv.visitInsn(ARETURN); mv.visitMaxs(2, 1); mv.visitEnd(); } { mv = cw.visitMethod(ACC_PUBLIC, "toUpperCase", "(Ljava/util/Locale;)Ljava/lang/String;", null, null); mv.visitCode(); mv.visitVarInsn(ALOAD, 1); Label l0 = new Label(); mv.visitJumpInsn(IFNONNULL, l0); mv.visitTypeInsn(NEW, "java/lang/NullPointerException"); mv.visitInsn(DUP); mv.visitMethodInsn(INVOKESPECIAL, "java/lang/NullPointerException", "<init>", "()V"); mv.visitInsn(ATHROW); mv.visitLabel(l0); mv.visitInsn(ICONST_0); mv.visitVarInsn(ISTORE, 2); Label l1 = new Label(); mv.visitLabel(l1); mv.visitVarInsn(ILOAD, 2); mv.visitVarInsn(ALOAD, 0); mv.visitFieldInsn(GETFIELD, "java/lang/String", "count", "I"); Label l2 = new Label(); mv.visitJumpInsn(IF_ICMPGE, l2); mv.visitVarInsn(ALOAD, 0); mv.visitFieldInsn(GETFIELD, "java/lang/String", "value", "[C"); mv.visitVarInsn(ALOAD, 0); mv.visitFieldInsn(GETFIELD, "java/lang/String", "offset", "I"); mv.visitVarInsn(ILOAD, 2); mv.visitInsn(IADD); mv.visitInsn(CALOAD); mv.visitVarInsn(ISTORE, 3); mv.visitVarInsn(ILOAD, 3); mv.visitLdcInsn(new Integer(55296)); Label l3 = new Label(); mv.visitJumpInsn(IF_ICMPLT, l3); mv.visitVarInsn(ILOAD, 3); mv.visitLdcInsn(new Integer(56319)); mv.visitJumpInsn(IF_ICMPGT, l3); mv.visitVarInsn(ALOAD, 0); mv.visitVarInsn(ILOAD, 2); mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/String", "codePointAt", "(I)I"); mv.visitVarInsn(ISTORE, 3); mv.visitVarInsn(ILOAD, 3); mv.visitMethodInsn(INVOKESTATIC, "java/lang/Character", "charCount", "(I)I"); mv.visitVarInsn(ISTORE, 4); Label l4 = new Label(); mv.visitJumpInsn(GOTO, l4); mv.visitLabel(l3); mv.visitInsn(ICONST_1); mv.visitVarInsn(ISTORE, 4); mv.visitLabel(l4); mv.visitVarInsn(ILOAD, 3); mv.visitMethodInsn(INVOKESTATIC, "java/lang/Character", "toUpperCaseEx", "(I)I"); mv.visitVarInsn(ISTORE, 5); mv.visitVarInsn(ILOAD, 5); mv.visitInsn(ICONST_M1); Label l5 = new Label(); mv.visitJumpInsn(IF_ICMPEQ, l5); mv.visitVarInsn(ILOAD, 3); mv.visitVarInsn(ILOAD, 5); Label l6 = new Label(); mv.visitJumpInsn(IF_ICMPEQ, l6); mv.visitJumpInsn(GOTO, l5); mv.visitLabel(l6); mv.visitVarInsn(ILOAD, 2); mv.visitVarInsn(ILOAD, 4); mv.visitInsn(IADD); mv.visitVarInsn(ISTORE, 2); mv.visitJumpInsn(GOTO, l1); mv.visitLabel(l2); mv.visitVarInsn(ALOAD, 0); mv.visitInsn(ARETURN); mv.visitLabel(l5); mv.visitVarInsn(ALOAD, 0); mv.visitFieldInsn(GETFIELD, "java/lang/String", "count", "I"); mv.visitIntInsn(NEWARRAY, T_CHAR); mv.visitVarInsn(ASTORE, 3); mv.visitInsn(ICONST_0); mv.visitVarInsn(ISTORE, 4); mv.visitVarInsn(ALOAD, 0); mv.visitFieldInsn(GETFIELD, "java/lang/String", "value", "[C"); mv.visitVarInsn(ALOAD, 0); mv.visitFieldInsn(GETFIELD, "java/lang/String", "offset", "I"); mv.visitVarInsn(ALOAD, 3); mv.visitInsn(ICONST_0); mv.visitVarInsn(ILOAD, 2); mv.visitMethodInsn(INVOKESTATIC, "java/lang/System", "arraycopy", "(Ljava/lang/Object;ILjava/lang/Object;II)V"); mv.visitVarInsn(ALOAD, 1); mv.visitMethodInsn(INVOKEVIRTUAL, "java/util/Locale", "getLanguage", "()Ljava/lang/String;"); mv.visitVarInsn(ASTORE, 5); mv.visitVarInsn(ALOAD, 5); mv.visitLdcInsn("tr"); Label l7 = new Label(); mv.visitJumpInsn(IF_ACMPEQ, l7); mv.visitVarInsn(ALOAD, 5); mv.visitLdcInsn("az"); mv.visitJumpInsn(IF_ACMPEQ, l7); mv.visitVarInsn(ALOAD, 5); mv.visitLdcInsn("lt"); Label l8 = new Label(); mv.visitJumpInsn(IF_ACMPNE, l8); mv.visitLabel(l7); mv.visitInsn(ICONST_1); Label l9 = new Label(); mv.visitJumpInsn(GOTO, l9); mv.visitLabel(l8); mv.visitInsn(ICONST_0); mv.visitLabel(l9); mv.visitVarInsn(ISTORE, 6); mv.visitVarInsn(ILOAD, 2); mv.visitVarInsn(ISTORE, 11); Label l10 = new Label(); mv.visitLabel(l10); mv.visitVarInsn(ILOAD, 11); mv.visitVarInsn(ALOAD, 0); mv.visitFieldInsn(GETFIELD, "java/lang/String", "count", "I"); Label l11 = new Label(); mv.visitJumpInsn(IF_ICMPGE, l11); mv.visitVarInsn(ALOAD, 0); mv.visitFieldInsn(GETFIELD, "java/lang/String", "value", "[C"); mv.visitVarInsn(ALOAD, 0); mv.visitFieldInsn(GETFIELD, "java/lang/String", "offset", "I"); mv.visitVarInsn(ILOAD, 11); mv.visitInsn(IADD); mv.visitInsn(CALOAD); mv.visitVarInsn(ISTORE, 9); mv.visitVarInsn(ILOAD, 9); mv.visitInsn(I2C); mv.visitLdcInsn(new Integer(55296)); Label l12 = new Label(); mv.visitJumpInsn(IF_ICMPLT, l12); mv.visitVarInsn(ILOAD, 9); mv.visitInsn(I2C); mv.visitLdcInsn(new Integer(56319)); mv.visitJumpInsn(IF_ICMPGT, l12); mv.visitVarInsn(ALOAD, 0); mv.visitVarInsn(ILOAD, 11); mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/String", "codePointAt", "(I)I"); mv.visitVarInsn(ISTORE, 9); mv.visitVarInsn(ILOAD, 9); mv.visitMethodInsn(INVOKESTATIC, "java/lang/Character", "charCount", "(I)I"); mv.visitVarInsn(ISTORE, 10); Label l13 = new Label(); mv.visitJumpInsn(GOTO, l13); mv.visitLabel(l12); mv.visitInsn(ICONST_1); mv.visitVarInsn(ISTORE, 10); mv.visitLabel(l13); mv.visitVarInsn(ILOAD, 6); Label l14 = new Label(); mv.visitJumpInsn(IFEQ, l14); mv.visitVarInsn(ALOAD, 0); mv.visitVarInsn(ILOAD, 11); mv.visitVarInsn(ALOAD, 1); mv.visitMethodInsn(INVOKESTATIC, "java/lang/ConditionalSpecialCasing", "toUpperCaseEx", "(Ljava/lang/String;ILjava/util/Locale;)I"); mv.visitVarInsn(ISTORE, 8); Label l15 = new Label(); mv.visitJumpInsn(GOTO, l15); mv.visitLabel(l14); mv.visitVarInsn(ILOAD, 9); mv.visitMethodInsn(INVOKESTATIC, "java/lang/Character", "toUpperCaseEx", "(I)I"); mv.visitVarInsn(ISTORE, 8); mv.visitLabel(l15); mv.visitVarInsn(ILOAD, 8); mv.visitInsn(ICONST_M1); Label l16 = new Label(); mv.visitJumpInsn(IF_ICMPEQ, l16); mv.visitVarInsn(ILOAD, 8); mv.visitLdcInsn(new Integer(65536)); Label l17 = new Label(); mv.visitJumpInsn(IF_ICMPLT, l17); mv.visitLabel(l16); mv.visitVarInsn(ILOAD, 8); mv.visitInsn(ICONST_M1); Label l18 = new Label(); mv.visitJumpInsn(IF_ICMPNE, l18); mv.visitVarInsn(ILOAD, 6); Label l19 = new Label(); mv.visitJumpInsn(IFEQ, l19); mv.visitVarInsn(ALOAD, 0); mv.visitVarInsn(ILOAD, 11); mv.visitVarInsn(ALOAD, 1); mv.visitMethodInsn(INVOKESTATIC, "java/lang/ConditionalSpecialCasing", "toUpperCaseCharArray", "(Ljava/lang/String;ILjava/util/Locale;)[C"); mv.visitVarInsn(ASTORE, 7); Label l20 = new Label(); mv.visitJumpInsn(GOTO, l20); mv.visitLabel(l19); mv.visitVarInsn(ILOAD, 9); mv.visitMethodInsn(INVOKESTATIC, "java/lang/Character", "toUpperCaseCharArray", "(I)[C"); mv.visitVarInsn(ASTORE, 7); mv.visitJumpInsn(GOTO, l20); mv.visitLabel(l18); mv.visitVarInsn(ILOAD, 10); mv.visitInsn(ICONST_2); Label l21 = new Label(); mv.visitJumpInsn(IF_ICMPNE, l21); mv.visitVarInsn(ILOAD, 4); mv.visitVarInsn(ILOAD, 8); mv.visitVarInsn(ALOAD, 3); mv.visitVarInsn(ILOAD, 11); mv.visitVarInsn(ILOAD, 4); mv.visitInsn(IADD); mv.visitMethodInsn(INVOKESTATIC, "java/lang/Character", "toChars", "(I[CI)I"); mv.visitVarInsn(ILOAD, 10); mv.visitInsn(ISUB); mv.visitInsn(IADD); mv.visitVarInsn(ISTORE, 4); Label l22 = new Label(); mv.visitJumpInsn(GOTO, l22); mv.visitLabel(l21); mv.visitVarInsn(ILOAD, 8); mv.visitMethodInsn(INVOKESTATIC, "java/lang/Character", "toChars", "(I)[C"); mv.visitVarInsn(ASTORE, 7); mv.visitLabel(l20); mv.visitVarInsn(ALOAD, 7); mv.visitInsn(ARRAYLENGTH); mv.visitVarInsn(ISTORE, 12); mv.visitVarInsn(ILOAD, 12); mv.visitVarInsn(ILOAD, 10); Label l23 = new Label(); mv.visitJumpInsn(IF_ICMPLE, l23); mv.visitVarInsn(ALOAD, 3); mv.visitInsn(ARRAYLENGTH); mv.visitVarInsn(ILOAD, 12); mv.visitInsn(IADD); mv.visitVarInsn(ILOAD, 10); mv.visitInsn(ISUB); mv.visitIntInsn(NEWARRAY, T_CHAR); mv.visitVarInsn(ASTORE, 13); mv.visitVarInsn(ALOAD, 3); mv.visitInsn(ICONST_0); mv.visitVarInsn(ALOAD, 13); mv.visitInsn(ICONST_0); mv.visitVarInsn(ILOAD, 11); mv.visitVarInsn(ILOAD, 4); mv.visitInsn(IADD); mv.visitMethodInsn(INVOKESTATIC, "java/lang/System", "arraycopy", "(Ljava/lang/Object;ILjava/lang/Object;II)V"); mv.visitVarInsn(ALOAD, 13); mv.visitVarInsn(ASTORE, 3); mv.visitLabel(l23); mv.visitInsn(ICONST_0); mv.visitVarInsn(ISTORE, 13); Label l24 = new Label(); mv.visitLabel(l24); mv.visitVarInsn(ILOAD, 13); mv.visitVarInsn(ILOAD, 12); Label l25 = new Label(); mv.visitJumpInsn(IF_ICMPGE, l25); mv.visitVarInsn(ALOAD, 3); mv.visitVarInsn(ILOAD, 11); mv.visitVarInsn(ILOAD, 4); mv.visitInsn(IADD); mv.visitVarInsn(ILOAD, 13); mv.visitInsn(IADD); mv.visitVarInsn(ALOAD, 7); mv.visitVarInsn(ILOAD, 13); mv.visitInsn(CALOAD); mv.visitInsn(CASTORE); mv.visitIincInsn(13, 1); mv.visitJumpInsn(GOTO, l24); mv.visitLabel(l25); mv.visitVarInsn(ILOAD, 4); mv.visitVarInsn(ILOAD, 12); mv.visitVarInsn(ILOAD, 10); mv.visitInsn(ISUB); mv.visitInsn(IADD); mv.visitVarInsn(ISTORE, 4); mv.visitJumpInsn(GOTO, l22); mv.visitLabel(l17); mv.visitVarInsn(ALOAD, 3); mv.visitVarInsn(ILOAD, 11); mv.visitVarInsn(ILOAD, 4); mv.visitInsn(IADD); mv.visitVarInsn(ILOAD, 8); mv.visitInsn(I2C); mv.visitInsn(CASTORE); mv.visitLabel(l22); mv.visitVarInsn(ILOAD, 11); mv.visitVarInsn(ILOAD, 10); mv.visitInsn(IADD); mv.visitVarInsn(ISTORE, 11); mv.visitJumpInsn(GOTO, l10); mv.visitLabel(l11); mv.visitTypeInsn(NEW, "java/lang/String"); mv.visitInsn(DUP); mv.visitInsn(ICONST_0); mv.visitVarInsn(ALOAD, 0); mv.visitFieldInsn(GETFIELD, "java/lang/String", "count", "I"); mv.visitVarInsn(ILOAD, 4); mv.visitInsn(IADD); mv.visitVarInsn(ALOAD, 3); mv.visitMethodInsn(INVOKESPECIAL, "java/lang/String", "<init>", "(II[C)V"); mv.visitInsn(ARETURN); mv.visitMaxs(6, 14); mv.visitEnd(); } { mv = cw.visitMethod(ACC_PUBLIC, "toUpperCase", "()Ljava/lang/String;", null, null); mv.visitCode(); mv.visitVarInsn(ALOAD, 0); mv.visitMethodInsn(INVOKESTATIC, "java/util/Locale", "getDefault", "()Ljava/util/Locale;"); mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/String", "toUpperCase", "(Ljava/util/Locale;)Ljava/lang/String;"); mv.visitInsn(ARETURN); mv.visitMaxs(2, 1); mv.visitEnd(); } { mv = cw.visitMethod(ACC_PUBLIC, "trim", "()Ljava/lang/String;", null, null); mv.visitCode(); mv.visitVarInsn(ALOAD, 0); mv.visitFieldInsn(GETFIELD, "java/lang/String", "count", "I"); mv.visitVarInsn(ISTORE, 1); mv.visitInsn(ICONST_0); mv.visitVarInsn(ISTORE, 2); mv.visitVarInsn(ALOAD, 0); mv.visitFieldInsn(GETFIELD, "java/lang/String", "offset", "I"); mv.visitVarInsn(ISTORE, 3); mv.visitVarInsn(ALOAD, 0); mv.visitFieldInsn(GETFIELD, "java/lang/String", "value", "[C"); mv.visitVarInsn(ASTORE, 4); Label l0 = new Label(); mv.visitLabel(l0); mv.visitVarInsn(ILOAD, 2); mv.visitVarInsn(ILOAD, 1); Label l1 = new Label(); mv.visitJumpInsn(IF_ICMPGE, l1); mv.visitVarInsn(ALOAD, 4); mv.visitVarInsn(ILOAD, 3); mv.visitVarInsn(ILOAD, 2); mv.visitInsn(IADD); mv.visitInsn(CALOAD); mv.visitIntInsn(BIPUSH, 32); mv.visitJumpInsn(IF_ICMPGT, l1); mv.visitIincInsn(2, 1); mv.visitJumpInsn(GOTO, l0); mv.visitLabel(l1); mv.visitVarInsn(ILOAD, 2); mv.visitVarInsn(ILOAD, 1); Label l2 = new Label(); mv.visitJumpInsn(IF_ICMPGE, l2); mv.visitVarInsn(ALOAD, 4); mv.visitVarInsn(ILOAD, 3); mv.visitVarInsn(ILOAD, 1); mv.visitInsn(IADD); mv.visitInsn(ICONST_1); mv.visitInsn(ISUB); mv.visitInsn(CALOAD); mv.visitIntInsn(BIPUSH, 32); mv.visitJumpInsn(IF_ICMPGT, l2); mv.visitIincInsn(1, -1); mv.visitJumpInsn(GOTO, l1); mv.visitLabel(l2); mv.visitVarInsn(ILOAD, 2); Label l3 = new Label(); mv.visitJumpInsn(IFGT, l3); mv.visitVarInsn(ILOAD, 1); mv.visitVarInsn(ALOAD, 0); mv.visitFieldInsn(GETFIELD, "java/lang/String", "count", "I"); Label l4 = new Label(); mv.visitJumpInsn(IF_ICMPGE, l4); mv.visitLabel(l3); mv.visitVarInsn(ALOAD, 0); mv.visitVarInsn(ILOAD, 2); mv.visitVarInsn(ILOAD, 1); mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/String", "substring", "(II)Ljava/lang/String;"); Label l5 = new Label(); mv.visitJumpInsn(GOTO, l5); mv.visitLabel(l4); mv.visitVarInsn(ALOAD, 0); mv.visitLabel(l5); mv.visitInsn(ARETURN); mv.visitMaxs(3, 5); mv.visitEnd(); } { mv = cw.visitMethod(ACC_PUBLIC, "toString", "()Ljava/lang/String;", null, null); mv.visitCode(); mv.visitVarInsn(ALOAD, 0); mv.visitInsn(ARETURN); mv.visitMaxs(1, 1); mv.visitEnd(); } { mv = cw.visitMethod(ACC_PUBLIC, "toCharArray", "()[C", null, null); mv.visitCode(); mv.visitVarInsn(ALOAD, 0); mv.visitFieldInsn(GETFIELD, "java/lang/String", "count", "I"); mv.visitIntInsn(NEWARRAY, T_CHAR); mv.visitVarInsn(ASTORE, 1); mv.visitVarInsn(ALOAD, 0); mv.visitInsn(ICONST_0); mv.visitVarInsn(ALOAD, 0); mv.visitFieldInsn(GETFIELD, "java/lang/String", "count", "I"); mv.visitVarInsn(ALOAD, 1); mv.visitInsn(ICONST_0); mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/String", "getChars", "(II[CI)V"); mv.visitVarInsn(ALOAD, 1); mv.visitInsn(ARETURN); mv.visitMaxs(5, 2); mv.visitEnd(); } { mv = cw.visitMethod(ACC_PUBLIC + ACC_STATIC + ACC_VARARGS, "format", "(Ljava/lang/String;[Ljava/lang/Object;)Ljava/lang/String;", null, null); mv.visitCode(); mv.visitTypeInsn(NEW, "java/util/Formatter"); mv.visitInsn(DUP); mv.visitMethodInsn(INVOKESPECIAL, "java/util/Formatter", "<init>", "()V"); mv.visitVarInsn(ALOAD, 0); mv.visitVarInsn(ALOAD, 1); mv.visitMethodInsn(INVOKEVIRTUAL, "java/util/Formatter", "format", "(Ljava/lang/String;[Ljava/lang/Object;)Ljava/util/Formatter;"); mv.visitMethodInsn(INVOKEVIRTUAL, "java/util/Formatter", "toString", "()Ljava/lang/String;"); mv.visitInsn(ARETURN); mv.visitMaxs(3, 2); mv.visitEnd(); } { mv = cw.visitMethod(ACC_PUBLIC + ACC_STATIC + ACC_VARARGS, "format", "(Ljava/util/Locale;Ljava/lang/String;[Ljava/lang/Object;)Ljava/lang/String;", null, null); mv.visitCode(); mv.visitTypeInsn(NEW, "java/util/Formatter"); mv.visitInsn(DUP); mv.visitVarInsn(ALOAD, 0); mv.visitMethodInsn(INVOKESPECIAL, "java/util/Formatter", "<init>", "(Ljava/util/Locale;)V"); mv.visitVarInsn(ALOAD, 1); mv.visitVarInsn(ALOAD, 2); mv.visitMethodInsn(INVOKEVIRTUAL, "java/util/Formatter", "format", "(Ljava/lang/String;[Ljava/lang/Object;)Ljava/util/Formatter;"); mv.visitMethodInsn(INVOKEVIRTUAL, "java/util/Formatter", "toString", "()Ljava/lang/String;"); mv.visitInsn(ARETURN); mv.visitMaxs(3, 3); mv.visitEnd(); } { mv = cw.visitMethod(ACC_PUBLIC + ACC_STATIC, "valueOf", "(Ljava/lang/Object;)Ljava/lang/String;", null, null); mv.visitCode(); mv.visitVarInsn(ALOAD, 0); Label l0 = new Label(); mv.visitJumpInsn(IFNONNULL, l0); mv.visitLdcInsn("null"); Label l1 = new Label(); mv.visitJumpInsn(GOTO, l1); mv.visitLabel(l0); mv.visitVarInsn(ALOAD, 0); mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Object", "toString", "()Ljava/lang/String;"); mv.visitLabel(l1); mv.visitInsn(ARETURN); mv.visitMaxs(1, 1); mv.visitEnd(); } { mv = cw.visitMethod(ACC_PUBLIC + ACC_STATIC, "valueOf", "([C)Ljava/lang/String;", null, null); mv.visitCode(); mv.visitTypeInsn(NEW, "java/lang/String"); mv.visitInsn(DUP); mv.visitVarInsn(ALOAD, 0); mv.visitMethodInsn(INVOKESPECIAL, "java/lang/String", "<init>", "([C)V"); mv.visitInsn(ARETURN); mv.visitMaxs(3, 1); mv.visitEnd(); } { mv = cw.visitMethod(ACC_PUBLIC + ACC_STATIC, "valueOf", "([CII)Ljava/lang/String;", null, null); mv.visitCode(); mv.visitTypeInsn(NEW, "java/lang/String"); mv.visitInsn(DUP); mv.visitVarInsn(ALOAD, 0); mv.visitVarInsn(ILOAD, 1); mv.visitVarInsn(ILOAD, 2); mv.visitMethodInsn(INVOKESPECIAL, "java/lang/String", "<init>", "([CII)V"); mv.visitInsn(ARETURN); mv.visitMaxs(5, 3); mv.visitEnd(); } { mv = cw.visitMethod(ACC_PUBLIC + ACC_STATIC, "copyValueOf", "([CII)Ljava/lang/String;", null, null); mv.visitCode(); mv.visitTypeInsn(NEW, "java/lang/String"); mv.visitInsn(DUP); mv.visitVarInsn(ALOAD, 0); mv.visitVarInsn(ILOAD, 1); mv.visitVarInsn(ILOAD, 2); mv.visitMethodInsn(INVOKESPECIAL, "java/lang/String", "<init>", "([CII)V"); mv.visitInsn(ARETURN); mv.visitMaxs(5, 3); mv.visitEnd(); } { mv = cw.visitMethod(ACC_PUBLIC + ACC_STATIC, "copyValueOf", "([C)Ljava/lang/String;", null, null); mv.visitCode(); mv.visitVarInsn(ALOAD, 0); mv.visitInsn(ICONST_0); mv.visitVarInsn(ALOAD, 0); mv.visitInsn(ARRAYLENGTH); mv.visitMethodInsn(INVOKESTATIC, "java/lang/String", "copyValueOf", "([CII)Ljava/lang/String;"); mv.visitInsn(ARETURN); mv.visitMaxs(3, 1); mv.visitEnd(); } { mv = cw.visitMethod(ACC_PUBLIC + ACC_STATIC, "valueOf", "(Z)Ljava/lang/String;", null, null); mv.visitCode(); mv.visitVarInsn(ILOAD, 0); Label l0 = new Label(); mv.visitJumpInsn(IFEQ, l0); mv.visitLdcInsn("true"); Label l1 = new Label(); mv.visitJumpInsn(GOTO, l1); mv.visitLabel(l0); mv.visitLdcInsn("false"); mv.visitLabel(l1); mv.visitInsn(ARETURN); mv.visitMaxs(1, 1); mv.visitEnd(); } { mv = cw.visitMethod(ACC_PUBLIC + ACC_STATIC, "valueOf", "(C)Ljava/lang/String;", null, null); mv.visitCode(); mv.visitInsn(ICONST_1); mv.visitIntInsn(NEWARRAY, T_CHAR); mv.visitInsn(DUP); mv.visitInsn(ICONST_0); mv.visitVarInsn(ILOAD, 0); mv.visitInsn(CASTORE); mv.visitVarInsn(ASTORE, 1); mv.visitTypeInsn(NEW, "java/lang/String"); mv.visitInsn(DUP); mv.visitInsn(ICONST_0); mv.visitInsn(ICONST_1); mv.visitVarInsn(ALOAD, 1); mv.visitMethodInsn(INVOKESPECIAL, "java/lang/String", "<init>", "(II[C)V"); mv.visitInsn(ARETURN); mv.visitMaxs(5, 2); mv.visitEnd(); } { mv = cw.visitMethod(ACC_PUBLIC + ACC_STATIC, "valueOf", "(I)Ljava/lang/String;", null, null); mv.visitCode(); mv.visitVarInsn(ILOAD, 0); mv.visitIntInsn(BIPUSH, 10); mv.visitMethodInsn(INVOKESTATIC, "java/lang/Integer", "toString", "(II)Ljava/lang/String;"); mv.visitInsn(ARETURN); mv.visitMaxs(2, 1); mv.visitEnd(); } { mv = cw.visitMethod(ACC_PUBLIC + ACC_STATIC, "valueOf", "(J)Ljava/lang/String;", null, null); mv.visitCode(); mv.visitVarInsn(LLOAD, 0); mv.visitIntInsn(BIPUSH, 10); mv.visitMethodInsn(INVOKESTATIC, "java/lang/Long", "toString", "(JI)Ljava/lang/String;"); mv.visitInsn(ARETURN); mv.visitMaxs(3, 2); mv.visitEnd(); } { mv = cw.visitMethod(ACC_PUBLIC + ACC_STATIC, "valueOf", "(F)Ljava/lang/String;", null, null); mv.visitCode(); mv.visitVarInsn(FLOAD, 0); mv.visitMethodInsn(INVOKESTATIC, "java/lang/Float", "toString", "(F)Ljava/lang/String;"); mv.visitInsn(ARETURN); mv.visitMaxs(1, 1); mv.visitEnd(); } { mv = cw.visitMethod(ACC_PUBLIC + ACC_STATIC, "valueOf", "(D)Ljava/lang/String;", null, null); mv.visitCode(); mv.visitVarInsn(DLOAD, 0); mv.visitMethodInsn(INVOKESTATIC, "java/lang/Double", "toString", "(D)Ljava/lang/String;"); mv.visitInsn(ARETURN); mv.visitMaxs(2, 2); mv.visitEnd(); } { mv = cw.visitMethod(ACC_PUBLIC + ACC_NATIVE, "intern", "()Ljava/lang/String;", null, null); mv.visitEnd(); } { mv = cw.visitMethod(ACC_PUBLIC + ACC_BRIDGE + ACC_SYNTHETIC, "compareTo", "(Ljava/lang/Object;)I", null, null); mv.visitCode(); mv.visitVarInsn(ALOAD, 0); mv.visitVarInsn(ALOAD, 1); mv.visitTypeInsn(CHECKCAST, "java/lang/String"); mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/String", "compareTo", "(Ljava/lang/String;)I"); mv.visitInsn(IRETURN); mv.visitMaxs(2, 2); mv.visitEnd(); } { mv = cw.visitMethod(ACC_STATIC, "<clinit>", "()V", null, null); mv.visitCode(); mv.visitInsn(ICONST_0); mv.visitTypeInsn(ANEWARRAY, "java/io/ObjectStreamField"); mv.visitFieldInsn(PUTSTATIC, "java/lang/String", "serialPersistentFields", "[Ljava/io/ObjectStreamField;"); mv.visitTypeInsn(NEW, "java/lang/String$CaseInsensitiveComparator"); mv.visitInsn(DUP); mv.visitInsn(ACONST_NULL); mv.visitMethodInsn(INVOKESPECIAL, "java/lang/String$CaseInsensitiveComparator", "<init>", "(Ljava/lang/String$1;)V"); mv.visitFieldInsn(PUTSTATIC, "java/lang/String", "CASE_INSENSITIVE_ORDER", "Ljava/util/Comparator;"); mv.visitInsn(RETURN); mv.visitMaxs(3, 0); mv.visitEnd(); } cw.visitEnd();return cw.toByteArray(); } }The code shows how to create most of the class artifacts. I would now explain parts of the code. However, I will use a simpler class for demonstration and also like to add appropriate comments. The reason why I discussed the above is that in case you get stuck about how to create a particular artifact, you can simply compile a class having it and then generate code using ASMifier to see how it is created. I will use the following code as an example. The class ClassCreationDemoMaker creates a class that would have been the result of compiling the class ClassCreationDemo. ClassCreationDemo.java package com.geekyarticles.asm;public class ClassCreationDemo { private int version; public int getVersion() { return version; }public void setVersion(int version) { this.version = version; }@Override public String toString(){ return "ClassCreationDemo: "+version; } }ClassCreationDemoMaker.java package com.geekyarticles.asm; import java.io.DataOutputStream; import java.io.FileOutputStream; import static org.objectweb.asm.Opcodes.*; import org.objectweb.asm.*;public class ClassCreationDemoMaker {public static byte[] dump () throws Exception {//ClassWriter is a class visitor that generates the code for the class ClassWriter cw = new ClassWriter(0); FieldVisitor fv; MethodVisitor mv; //Start creating the class. cw.visit(V1_6, ACC_PUBLIC + ACC_SUPER, "com/geekyarticles/asm/ClassCreationDemo", null, "java/lang/Object", null);{ //version field fv = cw.visitField(ACC_PRIVATE, "version", "I", null, null); fv.visitEnd(); } { //Implementing the constructor mv = cw.visitMethod(ACC_PUBLIC, "<init>", "()V", null, null); mv.visitCode(); mv.visitVarInsn(ALOAD, 0); mv.visitMethodInsn(INVOKESPECIAL, "java/lang/Object", "<init>", "()V"); mv.visitInsn(RETURN); mv.visitMaxs(1, 1); mv.visitEnd(); } { //getVersion Method mv = cw.visitMethod(ACC_PUBLIC, "getVersion", "()I", null, null); mv.visitCode(); mv.visitVarInsn(ALOAD, 0); mv.visitFieldInsn(GETFIELD, "com/geekyarticles/asm/ClassCreationDemo", "version", "I"); mv.visitInsn(IRETURN); mv.visitMaxs(1, 1); mv.visitEnd(); } { //setVersion Method mv = cw.visitMethod(ACC_PUBLIC, "setVersion", "(I)V", null, null); mv.visitCode(); mv.visitVarInsn(ALOAD, 0); mv.visitVarInsn(ILOAD, 1); mv.visitFieldInsn(PUTFIELD, "com/geekyarticles/asm/ClassCreationDemo", "version", "I"); mv.visitInsn(RETURN); mv.visitMaxs(2, 2); mv.visitEnd(); } { //toString method mv = cw.visitMethod(ACC_PUBLIC, "toString", "()Ljava/lang/String;", null, null); mv.visitCode(); mv.visitTypeInsn(NEW, "java/lang/StringBuilder"); mv.visitInsn(DUP); mv.visitLdcInsn("ClassCreationDemo: "); mv.visitMethodInsn(INVOKESPECIAL, "java/lang/StringBuilder", "<init>", "(Ljava/lang/String;)V"); mv.visitVarInsn(ALOAD, 0); mv.visitFieldInsn(GETFIELD, "com/geekyarticles/asm/ClassCreationDemo", "version", "I"); mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/StringBuilder", "append", "(I)Ljava/lang/StringBuilder;"); mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/StringBuilder", "toString", "()Ljava/lang/String;"); mv.visitInsn(ARETURN); mv.visitMaxs(3, 1); mv.visitEnd(); } cw.visitEnd();return cw.toByteArray(); } public static void main(String [] args) throws Exception{ DataOutputStream dout=new DataOutputStream(new FileOutputStream("ClassCreationDemo.class")); dout.write(dump()); dout.flush(); dout.close(); } }The fundamental principle of creating a class is to use an object of ClassWriter, which is a ClassVisitor, and then call different visit methods in it in proper order. In this case we have only created one field and three methods. It is mandatory to create the constructor. The code is very simple to understand. Note that after calling the visitMethod method in the ClassWriter, we have used the MethodWriter returned from it to write the code in the method. Here also note that we have manually allocated the maximum stack size for each method. We can alternatively use ClassWriter.COMPUTE_MAXS flag in the ClassWriter constructor to avoid doing this. Writing a class is always an in-memory process. This is because the constants used in the class always needs to be in the constant pool, which is near the start of the class and it stores all the field and method names and every other things. Modifying classes: Honestly, this is where ASM shines, because of its sheer ease of use. In this section, we are going to create the class ClassModifierDemo which modifies the class ClassModificationDemo. The job of the modifier is to insert a code in each method invocation (including constructors) that prints its name. ClassModifierDemo.java package com.geekyarticles.asm;import java.io.DataOutputStream; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream;import org.objectweb.asm.ClassReader; import org.objectweb.asm.ClassVisitor; import org.objectweb.asm.ClassWriter; import org.objectweb.asm.MethodVisitor; import org.objectweb.asm.Opcodes;public class ClassModifierDemo {public static class ModifierMethodWriter extends MethodVisitor{private String methodName; public ModifierMethodWriter(int api, MethodVisitor mv, String methodName) { super(api, mv); this.methodName=methodName; }//This is the point we insert the code. Note that the instructions are added right after //the visitCode method of the super class. This ordering is very important. @Override public void visitCode() { super.visitCode(); super.visitFieldInsn(Opcodes.GETSTATIC, "java/lang/System", "out", "Ljava/io/PrintStream;"); super.visitLdcInsn("method: "+methodName); super.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/io/PrintStream", "println", "(Ljava/lang/String;)V"); } } //Our class modifier class visitor. It delegate all calls to the super class //Only makes sure that it returns our MethodVisitor for every method public static class ModifierClassWriter extends ClassVisitor{ private int api; public ModifierClassWriter(int api, ClassWriter cv) { super(api, cv); this.api=api; }@Override public MethodVisitor visitMethod(int access, String name, String desc, String signature, String[] exceptions) {MethodVisitor mv= super.visitMethod(access, name, desc, signature, exceptions); ModifierMethodWriter mvw=new ModifierMethodWriter(api, mv, name); return mvw; } }public static void main(String[] args) throws IOException { InputStream in=ASMHelloWorld.class.getResourceAsStream("/com/geekyarticles/asm/ClassModificationDemo.class"); ClassReader classReader=new ClassReader(in); ClassWriter cw=new ClassWriter(ClassWriter.COMPUTE_MAXS); //Wrap the ClassWriter with our custom ClassVisitor ModifierClassWriter mcw=new ModifierClassWriter(Opcodes.ASM4, cw); classReader.accept(mcw, 0); //Write the output to a class file File outputDir=new File("out/com/geekyarticles/asm"); outputDir.mkdirs(); DataOutputStream dout=new DataOutputStream(new FileOutputStream(new File(outputDir,"ClassModificationDemo.class"))); dout.write(cw.toByteArray()); }}ClassModificationDemo.java package com.geekyarticles.asm;public class ClassModificationDemo {private int version; public int getVersion() { return version; }public void setVersion(int version) { this.version = version; }@Override public String toString(){ return "ClassCreationDemo: "+version; } public static void main(String[] args) { System.out.println(new ClassModificationDemo());}}This example is a combination of reading and creating a class. In this case we simply wrap the ClassWriter with our own ClassVisitor. It simply delegates all calls directly to the ClassWriter except the visitMethod, which in turn is written to wrap the MethodVisitor returned by the ClassWriter with our own. MethodVisitor also directly delegates all calls to the super class except visitCode, which it uses to insert the custom code. After running the program, a new version of ClassModificationDemo will be created in the out directory with proper package structure. Now we can run the ClassModificationDemo class from out directory and see the result. It will print which method is invoked when. Reference: Manipulating Java Class Files with ASM 4 – Part One : Hello World! from our JCG partner Debasish Ray Chawdhuri at the Geeky Articles blog....
jcg-logo

Best Of The Week – 2012 – W07

Hello guys, Time for the “Best Of The Week” links for the week that just passed. Here are some links that drew Java Code Geeks attention: * NetBeans IDE 7.1: Unlocking the Java EE 6 Platform: Java EE 6 specification is deeply integrated into NetBeans IDE 7.1 and this article helps you to map its various parts to the related tools provided by the IDE. JPA 2.0, EJB 3.1, JSF 2.0, Servlets 3.0, CDI 1.0 and JAX-RS 1.1 are discussed. Don’t forget to also check From Spring to Java EE 6. * Developer/Designer Cross Training (or how to get developers to do your work for you): In this presentation, developer and designer cross training is discussed, i.e. how to get designers to cooperate with developers from the early stages of a project in an attempt to create a product that more closely reflects the designer’s vision. * JEE6: Stress Testing Java EE 6 Applications, how to?: A detailed guide on how to perform stress testing on Java EE 6 applications. Open source tools like JMeter and jVisualVM are used in order to stress test a GlassFish application server. Also check out Profile your applications with Java VisualVM and Servlet 3.0 Async Processing for Tenfold Increase in Server Throughput. * Meetings: Where Work Goes to Die: Jeff Atwood discusses meetings and why the pose a threat to productivity. He also offers some advice on how to make the most of them, like keeping meeting shorter than an hour, having a clearly defined mission statement for every meeting etc. * Beyond “Big Data”: Here the author attempts to describe the term “big data”, which involves hdorizontally-scalable columnar data stores, distributed data analysis, data synergy and augmentation and the improved ability to recognize patterns. Don’t miss Hadoop: A Soft Introduction and Big Data analytics with Hive and iReport. * Easier Parallel Programming on Google App Engine: This article describes an interesting way of achieving parallel programming and using the fork/join approach for tasks running on Google App Engine. Also see Java Fork/Join for Parallel Programming and Spring MVC and REST at Google App Engine. * MySQL Cluster 7.2 Released with 70x Increased Performance and NoSQL Features: New release of MySQL Cluster from Oracle, with improvements in autosharding the data and replication conflict resolution in addition to some scalability and reliability improvements that allow replication at different data centers. Additionally, Oracle is claiming gains of up to 70x for complex queries (!?!). * Setup and use Play framework 2.0 in Scala IDE 2.0: This guide shows how to configure a Play web application to import it in Scala IDE, how to configure Scala IDE to work fine with the Play framework and how to develop Play web application from inside Scala IDE. Also see Play! Framework: Why Did I Fall in Love with it and Scala for 2012? Deciding Whether to Invest In a Programming Language. * Taming Android: This presentation shares tips on creating visually appealing Android applications that scale to various screen sizes. The session focuses on custom views, scalable drawables, and ListView. Also check out “Android Full Application Tutorial” series. * The Codypo Test, aka 8 Questions To Identify A Lame Programming Job: This article provides some hints on how to identify a lame programming job by comparing salary and the market rates, checking whether internet usage is filtered or monitored, whether maintaining any ancient system is involved etc. * Pretty Useless Javadocs: To lighten up, some examples of useless yet funny Javadocs. For even more laughs, check Funny Source Code Comments. * How to Analyze Java Thread Dumps: Very useful article on how to generate and analyze thread dumps in Java in order to identify deadlocks and poor performance in general. Command line tools and VisualVM are used for this purpose. Must read. * Adding Some Agility to Java EE Application Deployment with GlassFish: This article presents four noteworthy features in GlassFish that increase agility in Java EE application deployment: Session data preservation across redeployments, Servlet fragments, Application-scoped resources and Application versioning. Also see Zero-downtime Deployment (and Rollback) in Tomcat; a walkthrough and a checklist. * Real-time error monitoring in Google app engine: Quick guide on how to setup real-time error monitoring in Google App Engine and send a Google Talk message each time an error occurs. Nice and simple. That’s all for this week. Stay tuned for more, here at Java Code Geeks. Cheers, Ilias Tsagklis...
redmine-logo

Redmine Installation & Getting Started Guide

Redmine is a free and open source, flexible web-based project management and bug-tracking tool, written using the Ruby on Rails framework. Redmine supports multiple projects, with its own wiki, forum, time tracker and issues management. Moreover Redmine implements a plugin platform so can be customized depending on your requirements. Exists plugins to work with Kanban, Scrum, notification plugins or reports. What I really like about Redmine is that although does not fix the way you must work, it contains enough options to work in any kind of project management approach. Redmine can be installed in different ways:Using webrick (not recommended in production environments). Run with mongrel and fastcgi. Using Passenger. Or package Redmine into war and deploy into Java container like Tomcat or Glassfish.In this post I am going to show you how to package Redmine 1.3 into a war file so could be executed into Tomcat7 and Linux. In theory should be work with Glassfish, JBoss, or any other OS. First of all download JRuby 1.6.6, so open a terminal wget http://jruby.org.s3.amazonaws.com/downloads/1.6.6/jruby-bin-1.6.6.tar.gz And decompress downloaded file and move to /usr/share directory. tar xvzf jruby-bin-1.6.6.tar.gz sudo mv jruby-1.6.6/ /usr/share/jruby-1.6.6 Then update environment variables with JRuby installation directory. sudo gedit /etc/environment PATH= … :/usr/share/jruby-1.6.6/bin JRUBY_HOME="/usr/share/jruby-1.6.6"Finally try to execute jruby to see that has been installed correctly: jruby -v And JRuby version information should be printed on console. Next step is to install required gems: gem install rack -v=1.1.1 gem install rails -v=2.3.14 gem install rdoc -v=2.4.2 gem install activerecord-jdbcmysql-adapter -v=1.2.2 gem install warbler -v=1.3.2 gem install jruby-openssl -v=0.7.5 gem install rubytree -v=0.8.2 gem install i18n -v=0.4.2 gem install tree -v=0.2.1Redmine installation Download Redmine 1.3 and install them on /usr/share directory: wget http://rubyforge.org/frs/download.php/75597/redmine-1.3.0.tar.gztar xvzf redmine-1.3.0.tar.gz sudo mv redmine-1.3.0 /usr/share/redmine-1.3.0Redmine requires a database to work. In this case I had already installed mySQL5, but postgeSQL is supported too. So let’s configure mySQL into Redmine. cd /usr/share/redmine-1.3.0/config/ Installation comes with a database template configuration file, we are going to rename it and modify to suit our environment. Moreover Redmine contains different start up modes (production, development, test). In our case because we are configuring a production environment, only production section will be touched. cp database.yml.example database.yml sudo gedit database.ymlproduction: adapter: jdbcmysql database: redmine host: localhost username: redmine password: redmine encoding: utf8After this modification, it is time to create Redmine user and database into mySQL. mysql -u root -p create database redmine character set utf8; create user ‘redmine’@’localhost’ IDENTIFIED BY ‘redmine’; grant all privileges on redmine.* to ‘redmine’@’localhost’;Now it is time to initialize Redmine cd /usr/share/redmine-1.3.0 rake generate_session_storeNext step is required because we are installing Redmine 1.3, in next versions of Redmine 1.4 and beyond will not be necessary. Open config/environment.rb and comment next like: config.gem ‘rubytree’, :lib => ‘tree’ And then create database schema and fill them with default data with next scripts. RAILS_ENV=production rake db:migrate RAILS_ENV=production rake redmine:load_default_dataNow we are going to test that Redmine is correctly configured. For this purpose we are going to use webrick. cd /usr/share/redmine-1.3.0 jruby script/server webrick -e productionand open a browser at http://localhost:3000 to start checking installation. Redmine web page will be shown, you can login with username and password admin/admin At this point we have Redmine correctly installed. Configuring Email An issue tracker should be able to send mail to affected users when a new issue is created or modified by change. If your mail server requires tls security protocol you should install action_mailer_optional_tls plugin. This plugin requires git, if you don’t have installed yet, type: sudo apt-get install git and then run next command on Redmine directory: jruby script/plugin install git://github.com/collectiveidea/action_mailer_optional_tls.git Let’s configure email delivery: cd /usr/share/redmine-1.3.0/config/ cp configuration.yml.example configuration.yml sudo gedit configuration.ymlInside configuration file you will find common email settings. Depending on your email server these attributes can vary widely, so at this point I am going to show you a simple smtp server configuration using plain authentication at production environment. Go to last line of configuration.yml file and append next lines into production section. production: # this line is already present in configuration.yml. email_delivery: delivery_method: :smtp smtp_settings: address: "example.com" port: 25 authentication: :plain domain: 'example.com' user_name: 'myaccount' password: 'password'All attributes are self-explanatory. And before creating war file, let’s check that email is correctly configured. Again we use webrick. cd /usr/share/redmine-1.3.0 jruby script/server webrick -e productionThen open browser at http://localhost:3000 and log in with admin account. Adjust admin email by clicking on My Account link, and at Email section, set administrator email. After that we are going to test email configuration, from main menu, go to Administration -> Settings -> Email Notifications, add emission email and click on test email. After a few time, a test message will be sent to administrator email account. We have succeeded in Redmine installation, now it is time to package it to be deployed into Tomcat. Packaging Redmine Before starting, because of incompatibility with installed jruby-rack gem, we should run next commands to install 1.0.10 version of jruby-rack. gem uninstall jruby-rack gem install jruby-rack -v=1.0.10Warble command requires a configuration file. This file is created using next command: cd /usr/share/redmine-1.3.0 warble configcd config/ sudo gedit warble.rbEdit Warble::Config section and configure config.dirs, config.gems and config.webxml.rails.env sections as: Warbler::Config.new do |config| config.dirs = %w(app config lib log vendor tmp extra files lang) config.gems += ["activerecord-jdbcmysql-adapter", "jruby-openssl", "i18n", "rack", "tree"] config.webxml.rails.env = ENV['RAILS_ENV'] || 'production' endAnd finally run: warble And Redmine war has been created and is ready to be deployed into Tomcat. Although we have got a war file, I recommend not deleting Redmine installation directory because could be used in future to install new plugins, or modify any configuration. After a modification, calling warble command, a new war with that change would be created. I wish you have found this useful. Reference: Redmine Installation & Getting Started Guide from our JCG partner Alex Soto at the One Jar To Rule Them All blog....
java-logo

Virtualizing Your Java Applications: Best Practices (JavaOne 2011)

Justin Murray started his presentation ["Virtualizing Your Java Applications: Best Practices" (21860)] about five minutes early and began by saying that virtualization has arrived at the point where people no longer need to be concerned about taking advantage of virtualization. He said his presentation is about a year old and is the work of a team of people. The relatively smaller room (Nikko Carmel I/II) was packed and appeared to be close to standing-room only (ushers helped get everyone seated). The combination of the morning’s strategy keynote going slightly over, the people jammed into the ballroom as they tried to exit, and the early start of this presentation led to a lot of people coming in late and that was a little distracting. I don’t fault the speaker for starting early because he had a lot of good information to cover. The biggest problem was the logistical delay forced on people departing the keynote that had already gone over its planned end time. Muray had seven best practices for virtualization, only the first two (virtual machine memory and virtual CPUs/physical CPUs/threads) of which are particular to Java. Most people make their virtualization mistakes in the memory area rather than in the processing/CPU area. Murray pointed out that Java developers do not have to do anything to use virtualization; they don’t need to change any code and they don’t need to change any settings.Virtual Machine Memory CPUs Disk I/O Network I/O Timekeeping Micro-benchmarks Monitoring and ManagementAn easy-to-understand initial best practice for virtualizing Java applications is: “The Java heap needs to be in physical memory all of the time.” He also recommended using large memory pages. Don’t cram so many virtual machines into physical memory so that total maximum heap space from each VM’s use more memory than available in physical memory. Murray’s first formal best practice was “1. Virtual Machine Memory: Size the virtual machine’s memory to leave adequate space.” He noted that there is a formula for calculating the amount of memory to use to take into account many needs of that memory. He said that this formula is documented in a white paper and in a colleague’s book. Murray said that while it’s possible to have too much JVM memory for a small application, he generally favors having plenty of memory allocated for JVMs to use in virtualization. Murray also recommended using VMware Distributed Resource Scheduler (DRS). His one other advertising pitch was for vFabric Elastic Memory for Java (EM4J), which is delivered with VMware’s “flavor of Tomcat” called tc server. Murray stated that while overcommitting of memory in Java is concern in most cases, it is not when using tc server and EM4J. Murray also used esxtop. After covering memory issues, Murray moved onto covering CPUs. He started this section with observations about threads and virtual CPUs. His slide stated “A Java thread executes on one vCPU at any one time” and “A vCPU is scheduled on one physical CPU at any one time.” Murray added that most customers he has worked with are using four virtual CPUs, but that up to 32 are now supported.. Threads are often waiting on a monitor or socket to be freed and Murray maintains that most Java applications are not fully using theads. Generally, Murray favors using “the lowest number of virtual CPUs that is practical for your application.” Murray stated that using the command-line option -Xgcthreads is the equivalent of saying, “I know better than the JVM.” Murray stated that virtualization is not afraid of I/O any longer. He said that from a Java virtualization perspective, network I/O is more important than disk I/O. Murray pointed out that swapping is not good for VM on physical machine and it’s likewise not good for VM on virtual machine. A good piece of advice that should be more commonly understood (but doesn’t seem to be) that Murray provided is to only benchmark your own application and only make decisions based on benchmarking of the particular application. He added that using a “representative subset” of the application is not good enough. For monitoring and management, Murray recommended starting with one JVM process per machine and then scaling up to the number of desired JVMs in a virtual machine one at a time to determine the upper limit. His last bullet on that slide recommended using vCenter or esxtop to see which portions of the Java application are consuming resources. Murray’s “short story” is that Java developers generally do not need to adjust JVM garbage collection strategy, thread pool sizing, or JDBC connection pool sizing any differently for virtualization than they do for physical servers. The only command-line option that should be used is for specifying large pages. Murray talked about using Capacity Planner for about 30 days of collection to see which candidates are good candidates for virtualization. Murray pointed out that you cannot create hardware out thin air, so heavily utilized hardware will not be helped by virtualization in those cases. Murray concluded with, “Java Middleware and Applications should be virtualized.” Murray works for VMware and VMware offers an Enterprise Java Applications on VMware Best Practices Guide. Murray referenced VMware’s Technical White Papers during his presentation. Reference: JavaOne 2011: Virtualizing Your Java Applications: Best Practices from our JCG partner Dustin Marx at the Inspired by Actual Events blog....
enterprise-java-logo

Concurrency Pattern: Producer and Consumer

In my career spanning 15 years, the problem of Producer and Consumer is one that I have come across only a few times. In most programming cases, what we are doing is performing functions in a synchronous fashion where the JVM or the web container handles the complexities of multi-threading on its own. However, when writing certain kinds of use cases where we need this. Last week, I came across one such use case that sent me 3 years back when I last did it. However, the way it was done last time was very different. When I first heard the problem statement, I knew instantly what was needed. However, my approach to doing it this time was going to be different from last time. It had simply to do with how I am viewing technology in my life today. I will not go into any non-technical side and will jump straight into the problem and its solution. I started to look at what existed in the market and did come across a couple of posts that helped me in channelizing my thoughts in the right way. Problem Statement We need a solution for a batch migration. We are migrating data form System 1 to System 2 and in the process we need to do three tasks:Load data from Database based on groups Process the data Update the records loaded in step#1 with modificationsWe have to handle 100s of groups and each group will have around 40K records. You can imagine the amount of time it would take if we were to perform this exercise in a synchronous fashion. Image here explains this problem in an effective way.Producer Consumer: The ProblemProducer and Consumer Pattern Let us take a look at the Producer Consumer pattern to begin with. If you refer to the problem statement above and look at the image, we see that there are so many entities who are ready with their part of data. However, there are not enough workers who can process all the data. Hence, as the producers continue to line-up in a queue it just continues to grow. We see that the systems start to hog up threads and take a lot of time. Intermediate SolutionProducer Consumer: The Intermediate approchWe do have an intermediate solution. Refer to the image and you will immediately notice that the producers are piling up their work in a filing cabinet and the worker continues to pick it up as they get done with the previous task. However, this approach does have some glaring shortcomings:There is still one worker who has to do all the work. The external systems may be happy, but the task will still continue to exist until the worker has completed all of the tasks The producers will pile up their data in a queue and it needs resources to hold the same. Just as in this example the cabinet can fill up, the same can happen with the JVM resources too. We need to be careful how much data we are going to place in memory and in some cases it may not be much.The SolutionProducer Consumer: The SolutionThe solution is what we see everyday in many places – like the cinema hall queue, Petrol Pumps etc. There are so many people who come in to book a ticket and based on how many people come in, the more people are added to issue tickets. Essentially, refer to image here and you will notice that Producers will keep adding their jobs to the cabinet and we have more workers to handle the work load. Java provided concurrency package to solve this issue. Till now, I have always worked on threading at a much lower level and this was first time I was going to work with this package. As I started to explore the web and read fellow bloggers with what they have to say, I came across one very good article. It helped in understanding the use of BlockingQueue in a very effective manner. However, the solutions provided by Dhruba would not have helped me in achieving the high throughput which is needed. So, I started to explore the use of ArrayBlockingQueue for the same. The Controller This is the first class where the contract between the producers and consumers are managed. The controller will setup 1 thread for the Producer and 2 threads for the consumer. Based on the needs we can create as many threads as we need; and even can even read the data from a properties or do some dynamic magic. For now, we will keep this simple. package com.kapil.techieforever.producerconsumer; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.Future; public class TestProducerConsumer { public static void main(String args[]) { try { Broker broker = new Broker(); ExecutorService threadPool = Executors.newFixedThreadPool(3); threadPool.execute(new Consumer("1", broker)); threadPool.execute(new Consumer("2", broker)); Future producerStatus = threadPool.submit(new Producer(broker)); // this will wait for the producer to finish its execution. producerStatus.get(); threadPool.shutdown(); } catch (Exception e) { e.printStackTrace(); } } }I am using ExecuteService to create a thread pool and manage it. Instead of using the basic Thread implementation, this is a more effective way as it will handle the exiting and restarting the threads as needed. You will also notice that I am using Future class to get the status of the producer thread. This class is very effective and will halt my program from further execution. This is a nice way of replacing the “.join” method on the threads. Note: I am not using Future very effectively in this example; so you may have to try a few things as you feel fit. Also, you should note the Broker class which is being used as filing cabinet between the producers and consumers. We will see its implementation in just a little while. The Producer This class is responsible for producing the data that needs to be worked upon. package com.kapil.techieforever.producerconsumer; public class Producer implements Runnable { private Broker broker; public Producer(Broker broker) { this.broker = broker; } @Override public void run() { try { for (Integer i = 1; i < 5 + 1; ++i) { System.out.println("Producer produced: " + i); Thread.sleep(100); broker.put(i); } this.broker.continueProducing = Boolean.FALSE; System.out.println("Producer finished its job; terminating."); } catch (InterruptedException ex) { ex.printStackTrace(); } } }This class is doing the most simplest of things that it can do – adding an integer to the broker. Some key areas to note are: 1. There is a property on Broker which is updated in the end by the producer when its done producing. This is also known as the “final” or “poison” entry. This is used by the consumers to know that there are no more data coming up 2. I have used Thread.sleep to simulate that some producers may take more time to produce the data. You can tweak this value and see the consumers act The Consumer This class is responsible for reading the data from the broker and doing its job package com.kapil.techieforever.producerconsumer; public class Consumer implements Runnable { private String name; private Broker broker; public Consumer(String name, Broker broker) { this.name = name; this.broker = broker; } @Override public void run() { try { Integer data = broker.get(); while (broker.continueProducing || data != null) { Thread.sleep(1000); System.out.println("Consumer " + this.name + " processed data from broker: " + data); data = broker.get(); } System.out.println("Comsumer " + this.name + " finished its job; terminating."); } catch (InterruptedException ex) { ex.printStackTrace(); } } }This is again a simple class that reads the Integer and prints it on the console. However, key points to note are: 1. The loop to process data is an endless loop, that runs on two conditions – until the producer is consuming and there is some data with the broker 2. Again, the Thread.sleep is used to create effective and different scenarios The Broker package com.kapil.techieforever.producerconsumer; import java.util.concurrent.ArrayBlockingQueue; import java.util.concurrent.TimeUnit; public class Broker { public ArrayBlockingQueue queue = new ArrayBlockingQueue(100); public Boolean continueProducing = Boolean.TRUE; public void put(Integer data) throws InterruptedException { this.queue.put(data); } public Integer get() throws InterruptedException { return this.queue.poll(1, TimeUnit.SECONDS); } }The very first thing to note is that we are using ArrayBlockingQueue as the data holder. I am not going to say what this does, but insist you to read it on the JavaDocs here. however, I will explain that the producers are going to place the data in the queue and the consumers will fetch from the queue in FIFO format. But, if the producers are slow, the consumers will wait for data to come in and if the array is full, the producers will wait for it to fill up. Also, note that I am using the ‘poll’ function instead of get in the queue. This is to ensure that the consumers will not keep waiting for ever and the waiting will time out after a few seconds. This helps us in inter-communication and kill the consumers when all the data is processed. (Note: try replacing poll with get and you will see some interesting outputs). Code I have the code sitting on Google project hosting. Feel free to go across and download it from there. It is essentially an eclipse (Spring STS) project. You may also get additional packages and classes when you download it based on when you are downloading it. Feel free to look into those too and share your comments - You can browse the source code on the SVN browser or; - You can download it from the project itself. A side step solution Initially, I posted this solution in middle, but then I realized that this is not the way to do things and hence I took this out of the main content and placed it in the end. Another variant to the final solution would be that the workers/consumers do not take one job at a time to process, but they pick up multiple jobs together and go about finishing them before going to the next set. This approach can generate similar results, but in some cases where we have jobs who do not take same time to finish can essentially mean that some workers will end up sooner than others creating some bottleneck. And, if the jobs are allocated before hand which means that all the consumers will have all the jobs before they process (not producer-consumer pattern) then this problem can add up even more and lead to more delays to the processing logic. Related articlesQueues are the Devil’s own data structures (petewarden.typepad.com) Am I wrong about queues being Satan’s little helpers? (petewarden.typepad.com) http://code.google.com/p/disruptor/Reference: Concurrency Pattern: Producer and Consumer from our JCG partner Kapil Viren Ahuja at the Scratch Pad blog....
spring-logo

Set up a Spring 3 development environment

This tutorial explains in short how to set-up a typical environment to develop Spring based applications. There is no prerequesite to this tutorial other then a working Windows XP client with sufficient CPU power and memory. During the tutorial we will need to install the following components:Java 6 JDK Update 26 Eclipse IDE for Java EE Developers 3.6.2 (Helios) Maven 3.0.3 Tomcat 7.0.14I suggest that you create a folder where you drop all the stuff we need to set-up the environment. My Folder is C:\spring. I will call that <dev_home> when I refer to it. Note: Setting up a Spring environment is possible in different ways. See here for example on how to setup a dynamic web project in Eclipse using Maven for dependency management. Combine it with this link on how to download Spring dependencies into Eclipse using Maven. However, I personally prefer to do a step-by-step installation of the separate components and integrate them myself. This way I learn a lot about how the tools work together and how to integrate them – and how to fix them when something is not working! In this tutorial we will create a little demo project. It is the well known Spring MVC, Spring Core, JPA, Hibernate (“web container only”) development stack that we use. This stack is used successful in many  productive enterprise applications. The demo can be used to start development of your own enterprise project. Installing Java 6 JDK What you need first is – guess what – Java! You can download the Java JDK from here. Do not download NetBeans or Java EE. You do not need it. All you need is a Java JDK. So select the Java JDK download button. Then you select the download button for your operating system. For me that’s the good old Windows x86. You get Java as a self-extracting .exe-File. When the installer asks for the target installation directory, then make it <dev_home>/java. Installing Eclipse IDE for Java EE Developers What you do now is to install your integrated development environment. I prefer Eclipse for development. It has a huge community out there and all the stuff like Maven and Tomcat is integrated well with Eclipse. To download Eclipse perform the following steps:In <dev_home> create a subfolder called “eclipse”. Open your Web Browser. Go to Eclipse download page On the upper right, select the download link appropriate for your operating system. For me that’s Windows 32-bit. Follow the instructions to download the Eclipse ZIP-Package.When you downloaded the Eclipse package, you can unzip it to <dev_home>/eclipse. After you unzipped Eclipse this installation is complete. To start Eclipse you can double click the eclipse.exe file in the folder <dev_home>/eclipse. When you start Eclipse this way then what you get is the standard start up configuration. This can lead to some problems, e.g. out-of-memory exceptions. I suggest to start Eclipse with some start up parameters in a .cmd-File. The following listing shows my typical start up script: @echo off set DEV_HOME=C:\spring set JAVA_HOME=%DEV_HOME%\javaset PATH=%JAVA_HOME%\bin;%PATH%start %DEV_HOME%\eclipse\eclipse.exe -vm %JAVA_HOME%\bin\javaw.exe -showlocation -vmargs -server -Xms512m -Xmx1024m -XX:MaxPermSize=128m Let’s create your own start up script:In the <dev_home>/eclipse folder, create a text file called eclipse.cmd. Place the listing above into the file, save the file and close it. To start Eclipse, double click the eclipse.cmd file.If everything works, then you get the following screen:In Eclipse all your development sources are placed into Eclipse projects. All the projects are in your workspace. Here you can enter the directory where Eclipse creates the workspaceEnter <dev_home>/workspace into the “Workspace” field. Press “OK” button.You get the following screen in Eclipse if everything worked out.From here you do the following to get your Eclipse ready to develop applications.Choose Window/Close Perspective in the menu bar. Choose Window/Open Perspective/Other in the menu bar. Select the Java EE perspective and click “OK”.For now we leave Eclipse ‘cause there is other stuff to do. To close Eclipse select File/Exit in the menu bar. Creating the Eclipse Projects using Maven 3 In this tutorial we use Maven 3 to set-up the Eclipse project. Maven is very easy to use here. There are other alternatives when it comes to lifecycle tooling, e.g. Gradle or ANT. I still use ANT a lot because I like to have full control over things. However, for the sake of simplicity in this tutorial we use Maven 3 because it makes standard project setup very easy. To get a copy of Maven 3 do the following:Go to Maven download page. Select the Mirror apache-maven-3.0.3-bin.zip(for Windows). Select the Mirror where you want to download the copy. Extract the ZIP-File into <dev_home>/maven.“Maven will run with sensible defaults, so you can get right into it. However, if you are operating under a restricted environment or behind a firewall, you might need to prepare to run Maven, as it requires write access to the home directory (C:\Documents and Settings\username\.m2 on Windows) and network access to download binary dependencies.” See here on how to configure a proxy server. (from the Maven manual) Now after we downloaded and extracted Maven, we can use it. Do the following:Start a command prompt window Go to <dev_home>/workspace Set the PATH variable as follows: set PATH=<dev_home>\maven\bin;%PATH%. Do not forget to replace <dev_home> with your development environment home directory.Type mvn –version. Maven should now talk to you and answer something like this:Now we are ready to create the Eclipse project. Maven uses archetypes that set-up a complete project for you. There are lots of archetypes available. To get a list just enter mvn archetype:generate. This will start an interactive batch utility where you can see all the archetypes that Maven supports out of the box. Because we know that we want to create a Spring project we don’t need interactive mode. Type in the following to create the Spring project:mvn archetype:generate -DarchetypeGroupId=org.fluttercode.knappsack -DarchetypeArtifactId=spring-mvc-jpa-demo-archetype -DarchetypeVersion=1.1 -DgroupId=com.mycompany.springapp -DartifactId=my-spring-app -Dversion=1.0-SNAPSHOT -DinteractiveMode=falseIn your <dev_home>/workspace folder there should now be a new folder called my-spring-app. Change into that directory. Open the pom.xml file to see the dependencies of your project. The pom.xml file is Maven’s main configuration file. All that’s specified as project dependency here is downloaded by Maven. In fact, Maven also checks if you have transitive dependencies because it analyzes the dependencies of your direct dependencies. This way, you don’t have the burden to stick the stuff together manually. Thank god for this very helpful feature! In the command prompt enter the following Maven command: mvn eclipse:eclipse. This will generate a complete Eclipse project into the current folder. It will take its time,because Maven downloads all the dependent libraries you need to run your Spring application. You can really go and take a coffee now. If everything worked, then you see the following at the end of the Maven console output:Now you’re done, in terms of creating the Eclipse project with all the Spring dependencies. Note: You noticed that Spring downloaded a lot of stuff to get all the things running. Spring provides lots of features and is very downwards compatible. Many people complain because it’s not lightweight anymore. They refer to exactly this list of dependencies. My opinion is that there is no alternative. Other approaches do exactly the same, but just behind the scenes. Often, if something goes wrong then, you don’t know why. When you use Spring at least you know your dependencies, you know what you get and need. There is nothing hided. I prefer to understand exactly this technical stuff so I can help myself if something goes wrong. Note: If you are setting up a Java EE 6 environment then continue in the Java EE 6 tutorial. The rest of this tutorial here is specific to Spring set-up.Adding the new project to Eclipse workspace We have got to make the project visible to Eclipse. Perform the following steps.To open Eclipse, go to <dev_home>/eclipse and double click eclipse.cmd. If the Workspace Dialog appears then make sure you select the correct workspace under <dev_home>/workspace. Press “OK”.In Eclipse select File/Import from the menu bar.  In the Import Dialog select “Existing Projects into Workspace” and select “Next”.Select <dev_home>/workspace/my-spring-app as your root directory for the project.Press “Finish”.The Project will be imported. When the import is finished you will recognise that the “Marker” view at the bottom shows various errors and warnings.Right now, Eclipse does not know where Maven placed the Spring libraries (JAR-files). When you downloaded the dependencies that are specified in pom.xml file, Maven placed the jar-files into the local repository. Now, Eclipse – by default – does not know where this Maven repository is on your local machine. Therefore Eclipse cannot build the project. As a result the “Markers” view at the bottom shows various error messages.You can easily set the missing environment variable using Maven. To do that, do the following:Close Eclipse with File/Exit from the menu bar. Go to the command window we have opened previously.  Type in: mvn -Declipse.workspace=<dev_home>/workspace eclipse:add-maven-repo. Press enter. Maven will now create the variable for you.Open Eclipse again (double click on <dev_home>/eclipse/eclipse.cmd) In Eclipse select Project/Clean in the menu bar, then select “Clean all Projects” and press OK in the dialog box. Eclipse will recompile the sources now. Remember this, you will need it once in a while when you work with Eclipse.The build path errors disappeared in the “Marker” view.If you work behind a firewall, Eclipse cannot access the internet to validate the syntax of  some XML-files. You need to configure the proxy settings.Go to Window/Preferences from the menu bar. On the Preferences Tab go to General/Network Connections. Set “Active Provider” to “Manual” and make the changes in the selected proxy settings.This again should decrease the number of warnings in the Marker view. Ignore the other warnings for now. Everything will work out fine. Installing Tomcat 7 Next you need a container where you can deploy your spring application. I use Tomcat as the container for local development.Go to Tomcat download page. Download the 32-bit Windows ZIP-File. In your <dev_home> folder create a new “tomcat” folder and extract tomcat there. Go to Eclipse Workbench. In the menu bar select Window/Show View/Servers Right click into the view and select New/Server from the context menu.In the New Server dialog select Apache/Tomcat v7.0 Server and click “Next”.In the next dialog enter <dev_home>/tomcat as installation directory. Click “Next”.On the next page select my-spring-app and click “Add” to configure that Eclipse uses the new Server as runtime container. Select “Finnish”.Now Eclipse is configured. It knows that you use Tomcat 7 as web container and your new Spring application will be deployed properly to test it in your local environment. Note: “Eclipse forgets to copy the Tomcat default apps (ROOT, examples, etc.) when it creates a Tomcat folder inside the Eclipse workspace. Go to C:\apache-tomcat-7.0.8\webapps, R-click on the ROOT folder and copy it. Then go to your Eclipse workspace, go to the .metadata folder, and search for “wtpwebapps”. You should find something like your-eclipse-workspace\.metadata\.plugins\org.eclipse.wst.server.core\tmp0\wtpwebapps (or …/tmp1/wtpwebapps if you already had another server registered in Eclipse). Go to the wtpwebapps folder, R-click, and paste ROOT (say “yes” if asked if you want to merge/replace folders/files). Then reload http://localhost/ to see the Tomcat welcome page.” (from: coreservlets.com) Starting and using the demo application You can test your installation now. What you do is the following:In Eclipse start your Tomcat Server. Go to “Servers” View.Select the Tomcat server and right click into the context menu. Select “Debug”. This will start the Tomcat server in debug-mode. You can see the server log coming up in Eclipse. Select “Console” View and notice that Tomcat talks to you. Make sure you don’t see any exception traces here.Now since Tomcat has started,open your Browser and go to: http://localhost:8080/my-spring-app This will open your Spring application. Play around a little.You’re done! You have installed and started a typical Spring development environment. This set up will be the prerequisite for my subsequent Spring tutorials. I will introduce you to the different features of the Spring Framework. Some errors that you may have and the solution Can not find the tag library descriptor for “http://java.sun.com/jsp/jstl/core” You can set the Target Runtime in the Eclipse project to the server which will execute the web application (e.g. for JSF: Glassfish) and Eclipse will then load the required libraries from there. Go to “Project -> Properties -> Targeted Runtime” and select your runtime. Reference: “Setting up a Spring 3 development environment” from our JCG partner Niklas....
Java Code Geeks and all content copyright © 2010-2014, Exelixis Media Ltd | Terms of Use | Privacy Policy
All trademarks and registered trademarks appearing on Java Code Geeks are the property of their respective owners.
Java is a trademark or registered trademark of Oracle Corporation in the United States and other countries.
Java Code Geeks is not connected to Oracle Corporation and is not sponsored by Oracle Corporation.
Do you want to know how to develop your skillset and become a ...
Java Rockstar?

Subscribe to our newsletter to start Rocking right now!

To get you started we give you two of our best selling eBooks for FREE!

Get ready to Rock!
You can download the complementary eBooks using the links below:
Close